文章出處

您不僅限于使用內置的綁定,如click,value綁定等,您可以創建自己的綁定。 這是如何控制視圖模型如何與DOM元素進行交互,并且為您提供了大量的靈活性,以便于以復用的方式封裝復雜的行為。

注冊綁定

要注冊綁定,請將其作為ko.bindingHandlers的子屬性添加,比如如下例子:

ko.bindingHandlers.yourBindingName = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        // 這是首次運行綁定的初始化回調函數
        // 在此處設置初始狀態和事件處理程序
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        // 當綁定首次應用到元素時,將調用一次
        // 每當監控屬性/計算屬性的值發生變化時
        // 每當DOM綁定的元素值方法變化時被調用.
    }
};

然后你可以使用它在任何數量的DOM元素:

<div data-bind="yourBindingName: someValue"> </div>

注意:你實際上不必提供完整的init和update回調 - 你可以只提供一個或另一個。

‘update’回調函數

當綁定應用于元素并跟蹤您訪問的任何依賴性(observables / computeds)時,Knockout將最初調用update回調。 當任何這些依賴關系改變時,將再次調用update回調。 將以下參數傳遞給它:

  • element — 此綁定中涉及的DOM元素
  • valueAccessor — 可以調用的JavaScript函數,以獲取此綁定中涉及的當前模型屬性。 調用此函數而不傳遞任何參數(即調用valueAccessor())以獲取當前模型屬性值。 要容易接受observable和plain值,請對返回的值調用ko.unwrap。
  • allBindings —可用于訪問綁定到此DOM元素的所有模型值的JavaScript對象。 調用allBindings.get('name')檢索名稱綁定的值(如果綁定不存在則返回undefined); 或allBindings.has('name')來確定當前元素是否存在名稱綁定。
  • viewModel — 此參數在Knockout 3.x中已棄用。 使用bindingContext。$ data或bindingContext $ raw用于訪問視圖模型的數據。
  • bindingContext — 保存可用于此元素的綁定的綁定上下文的對象。 此對象包括特殊屬性,包括$ parent,$ parents和$ root,可用于訪問與此上下文的祖先綁定的數據。

例如,您可能已經使用可見綁定控制元素的可見性,但現在您想要進一步進行和動畫轉換。 您希望元素根據observable的值滑入和滑出存在。 你可以通過編寫調用jQuery的slideUp / slideDown函數的自定義綁定來實現:

You have selected the option

源碼:

<div data-bind="slideVisible: giftWrap, slideDuration:600">You have selected the option</div>
<label><input type="checkbox" data-bind="checked: giftWrap" /> Gift wrap</label>
 
<script type="text/javascript">
    var viewModel = {
        giftWrap: ko.observable(true)
    };
    ko.bindingHandlers.slideVisible = {
    update: function(element, valueAccessor, allBindings) {
        // First get the latest data that we're bound to
        var value = valueAccessor();
 
        // Next, whether or not the supplied model property is observable, get its current value
        var valueUnwrapped = ko.unwrap(value);
 
        // Grab some more data from another binding property
        var duration = allBindings.get('slideDuration') || 400; // 400ms is default duration unless otherwise specified
 
        // Now manipulate the DOM element
        if (valueUnwrapped == true)
            $(element).slideDown(duration); // Make the element visible
        else
            $(element).slideUp(duration);   // Make the element invisible
        }
    };
    ko.applyBindings(viewModel);
</script>

當然,乍一看很多的代碼,但一旦你創建了你的自定義綁定,他們可以很容易地重用在許多地方。

‘init’回調函數

Knockout將為您使用綁定的每個DOM元素調用一次init函數。 init有兩個主要用途:

  • 為DOM元素設置初始狀態
  • 注冊任何事件處理程序,例如,當用戶單擊或修改DOM元素時,可以更改關聯的可觀察事件的狀態

KO將傳遞給init的參數和update回調具有完全相同的參數集。

繼續前面的示例,您可能希望使用slideVisible將元素設置為在頁面第一次出現時立即可見或不可見(沒有任何動畫幻燈片),以便動畫只在用戶更改模型狀態時運行。 你可以這樣做:

You have selected the option

源碼:

ko.bindingHandlers.slideVisible = {
    init: function(element, valueAccessor) {
        var value = ko.unwrap(valueAccessor()); // Get the current value of the current property we're bound to
        $(element).toggle(value); // jQuery will hide/show the element depending on whether "value" or true or false
    },
    update: function(element, valueAccessor, allBindings) {
        // Leave as before
    }
};

這意味著如果giftWrap被定義為初始狀態為false(即,giftWrap:ko.observable(false)),則相關聯的DIV最初將被隱藏,然后當用戶稍后檢查該框時滑入視圖。

在DOM事件后修改observable

您已經了解如何使用udpate,以便在監控屬性的更改時,可以更新關聯的DOM元素。 但是在另一個方向的事件呢? 當用戶對DOM元素執行某些操作時,您可能需要更新關聯的監控屬性。

您可以使用init回調作為注冊事件處理程序的地方,這將對關聯的observable進行更改。 例如

Name:

You're editing the name

源碼:

<p>Name: <input data-bind="hasFocus: editingName" /></p>
 
<!-- Showing that we can both read and write the focus state -->
<div data-bind="visible: editingName">You're editing the name</div>
<button data-bind="enable: !editingName(), click:function() { editingName(true) }">Edit name</button>
 
<script type="text/javascript">
    var viewModel = {
        editingName: ko.observable()
    };
    ko.bindingHandlers.hasFocus = {
        init: function(element, valueAccessor) {
            $(element).focus(function() {
                var value = valueAccessor();
                value(true);
            });
            $(element).blur(function() {
                var value = valueAccessor();
                value(false);
            });
        },
        update: function(element, valueAccessor) {
            var value = valueAccessor();
            if (ko.unwrap(value))
            element.focus();
            else
                element.blur();
        }
    };
    ko.applyBindings(viewModel,document.getElementById('eq3'));
</script>

現在,您可以通過將元素綁定到可監控對象來讀取和寫入元素的“焦點”。

備注,虛擬綁定

如果您希望自定義綁定可用于Knockout虛擬元素語法,可使用如下寫法:

<!-- ko mybinding: somedata --> ... <!-- /ko -->

文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()