Knockoutjs實戰開發:創建自定義綁定(Creating custom bindings)


在使用Knockoutjs時我們並不僅僅限於使用內建的綁定,比如:click、value等,我們可以創建自己的綁定規則。Knockoutjs為我們提供了非常靈活的支持,能夠讓我們自己去處理非常復雜的業務並且構造出可重用性的綁定。例如我們可以創建交互式的組件,比如表格、網格等。下面我們就來看看怎么一步步創建自定義綁定。

一、等級我們的綁定(Registering your binding)

我們可以通過ko.bindingHandlers來進行綁定。

 1 ko.bindingHandlers.yourBindingName = { 
 2     init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
 3         // This will be called when the binding is first applied to an element 
 4         // Set up any initial state, event handlers, etc. here 
 5     }, 
 6     update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
 7         // This will be called once when the binding is first applied to an element, 
 8         // and again whenever the associated observable changes value. 
 9         // Update the DOM element based on the supplied values here. 
10     } 
11 };

接着我們就可以在DOM元素中使用我們自定義的綁定了。

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

注:在實際使用中你不用同時提供init和update兩個方法,在使用時你只需要提供其中的一個也可以。
下面我們就介紹一下這兩個函數。

(1)、update

當你所綁定的組件的值改變時,會自動調用update回調函數,並且傳遞一下的參數:

  (a)、element:被綁定的DOM element

  (b)、valueAccessor:這是一個JavaScript函數,在這個函數中你可以得到你所綁定的當前元素的屬性的值。

  (c)、allBindingsAccessor:通過此JavaScript函數,我們可以得到綁定到此DOM element上的所有屬性的值。

  (d)、viewModel:將試圖模型對象傳遞給ko.applyBindings。如果在一個嵌套的元素中使用的話,此參數代表的是當前的數據項,比如:在with:person中,此參數代表person。

  (e)、bindingContext:一個包含對這個元素可用的上下文的對象,這個對象中包含了一些特殊的屬性,比如:$parent、$parents、$root等。

我們之前曾經使用visible來控制一個綁定是否顯示,此時我們可以通過自定義綁定實現動態的效果,比如出現和消失時都采用滑動的效果,我們則可以這樣定義自己的方法:

 1 ko.bindingHandlers.slideVisible = { 
 2     update: function(element, valueAccessor, allBindingsAccessor) { 
 3         // First get the latest data that we're bound to 
 4         var value = valueAccessor(), allBindings = allBindingsAccessor(); 
 5           
 6         // Next, whether or not the supplied model property is observable, get its current value 
 7         var valueUnwrapped = ko.utils.unwrapObservable(value);  
 8           
 9         // Grab some more data from another binding property 
10         var duration = allBindings.slideDuration || 400; // 400ms is default duration unless otherwise specified 
11           
12         // Now manipulate the DOM element 
13         if (valueUnwrapped == true)  
14             $(element).slideDown(duration); // Make the element visible 
15         else 
16             $(element).slideUp(duration);   // Make the element invisible 
17     } 
18 };

在這里我們使用了jQuery的slideDown和slideUp函數。
現在我們就可以使用自己的綁定功能了:

1 <div data-bind="slideVisible: giftWrap, slideDuration:600">You have selected the option</div> 
2 <label><input type="checkbox" data-bind="checked: giftWrap" /> Gift wrap</label> 
3   
4 <script type="text/javascript"> 
5     var viewModel = { 
6         giftWrap: ko.observable(true) 
7     }; 
8     ko.applyBindings(viewModel); 
9 </script>

(2)、init
通過init函數我們可以在實例DOM元素的時候去做一些事情,我們經常在以下兩種情況使用init函數:

(a)、為DOM elements設置初始狀態。

(b)、注冊事件處理程序,這樣當用戶點擊綁定的DOM elements時就會觸動對應的事件,我們也可以對其作出反映。

我們可以為上例增加一個init函數,當頁面初次加載時我們可以控制是否顯示組件:

1 ko.bindingHandlers.slideVisible = { 
2     init: function(element, valueAccessor) { 
3         var value = ko.utils.unwrapObservable(valueAccessor()); // Get the current value of the current property we're bound to 
4         $(element).toggle(value); // jQuery will hide/show the element depending on whether "value" or true or false 
5     }, 
6     update: function(element, valueAccessor, allBindingsAccessor) { 
7         // Leave as before 
8     } 
9 };

二、在DOM事件后修改可見值。
前面我們已經介紹了如何使用update,這樣當一個DOM元素更新時我們可以作出對應的更新,但是我們怎么定義到某個具體的值呢,此時我們就可以使用如下的方法:

 1 ko.bindingHandlers.hasFocus = { 
 2     init: function(element, valueAccessor) { 
 3         $(element).focus(function() { 
 4             var value = valueAccessor(); 
 5             value(true); 
 6         }); 
 7         $(element).blur(function() { 
 8             var value = valueAccessor(); 
 9             value(false); 
10         });            
11     }, 
12     update: function(element, valueAccessor) { 
13         var value = valueAccessor(); 
14         if (ko.utils.unwrapObservable(value)) 
15             element.focus(); 
16         else
17             element.blur(); 
18     } 
19 };

此時我們就可以在UI進行使用了:

 1 <p>Name: <input data-bind="hasFocus: editingName" /></p> 
 2   
 3 <!-- Showing that we can both read and write the focus state --> 
 4 <div data-bind="visible: editingName">You're editing the name</div> 
 5 <button data-bind="enable: !editingName(), click:function() { editingName(true) }">Edit name</button> 
 6   
 7 <script type="text/javascript"> 
 8     var viewModel = { 
 9         editingName: ko.observable() 
10     }; 
11     ko.applyBindings(viewModel); 
12 </script>

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM