Knockoutjs實戰開發:控制子綁定(control descendant bindings)


在上一篇文章中我們介紹了如何來創建一個自定義綁定,今天我們就繼續來學習如何來控制子綁定(control descendant bindings)。在此之前我們首先說明一下,此項功能相對來說比較高級,通常我們在創建自己的可重用的庫時我們才會使用,不是說當我們在使用Knockoutjs創建我們的應用時一定要使用此項功能的。

在默認情況下,一個綁定只對它所綁定的element元素起作用。但是如果我們想要此綁定對它所綁定的element的所有子element起作用我們應該怎么辦呢?我們在自定義binding的時候我們可以告訴Knockoutjs不綁定他的子元素,這樣我們自己定義的綁定就可以以我們喜歡的方式任意綁定了。我們只需要在init函數中返回{ controlsDescendantBindings: true }即可

一、控制是否對子綁定起作用

我們來舉一個非常簡單的例子,我們自定義一個綁定名為:allowBindings,這樣如果他的值為true的話我們就進行子綁定。如果他的值為false則不會對子綁定起任何作用。

1 <script type="text/javascript">
2     ko.bindingHandlers.allowBindings = {
3         init: function (elem, valueAccessor) {
4             // Let bindings proceed as normal *only if* my value is false 
5             var shouldAllowBindings = ko.utils.unwrapObservable(valueAccessor());
6             return { controlsDescendantBindings: !shouldAllowBindings };
7         }
8     };
9 </script>

我們可以在UI中使用此綁定:

1 <div data-bind="allowBindings: true"> 
2     <!-- This will display Replacement, because bindings are applied --> 
3     <div data-bind="text: 'Replacement'">Original</div> 
4 </div> 
5   
6 <div data-bind="allowBindings: false"> 
7     <!-- This will display Original, because bindings are not applied --> 
8     <div data-bind="text: 'Replacement'">Original</div> 
9 </div>

 

二、為子綁定提供額外的值

我們定義一個綁定:withProperties,它中的屬性可以被他的所有子綁定得到:

 1 <script type="text/javascript">
 2     ko.bindingHandlers.withProperties = {
 3         init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
 4             // Make a modified binding context, with a extra properties, and apply it to descendant elements 
 5             var newProperties = valueAccessor(),
 6             innerBindingContext = bindingContext.extend(newProperties);
 7             ko.applyBindingsToDescendants(innerBindingContext, element);
 8 
 9             // Also tell KO *not* to bind the descendants itself, otherwise they will be bound twice 
10             return { controlsDescendantBindings: true };
11         }
12     };
13 </script>

正如我們所看到的那樣,我們使用extend函數來產生額外屬性的克隆,這並不影響我們本身元素的值,所以對於他同級別的元素也是沒有影響的,它僅僅對它的字元素有影響。

下面我們就可以使用上面自定義的綁定了:

1 <div data-bind="withProperties: { emotion: 'happy' }"> 
2     Today I feel <span data-bind="text: emotion"></span>. <!-- Displays: happy --> 
3 </div> 
4 <div data-bind="withProperties: { emotion: 'whimsical' }"> 
5     Today I feel <span data-bind="text: emotion"></span>. <!-- Displays: whimsical --> 
6 </div>

 

三、在上下文層次結構中添加額外的水平綁定

例如with、foreach綁定可以在同等級的上下文層次結構中綁定相應的水平綁定,這樣我們就可以在子綁定中使用$parent、$parents、$root、$parentContext來調用外面的屬性。如果我們想要在自定義的綁定中使用此功能的話,這種情況下我們就不是使用上例提到的bindingContext.extend(),而是使用bindingContext.createChildContext(someData)。這樣它就返回一個新的綁定上下文,他的viewmodel是someData,它的$parentContext就是bindingContext。如果你願意的話你可以使用ko.utils.extend來擴展子上下文。

 1 <script type="text/javascript">
 2     ko.bindingHandlers.withProperties = {
 3         init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
 4             // Make a modified binding context, with a extra properties, and apply it to descendant elements 
 5             var newProperties = valueAccessor(),
 6             childBindingContext = bindingContext.createChildContext(viewModel);
 7             ko.utils.extend(childBindingContext, newProperties);
 8             ko.applyBindingsToDescendants(childBindingContext, element);
 9 
10             // Also tell KO *not* to bind the descendants itself, otherwise they will be bound twice 
11             return { controlsDescendantBindings: true };
12         }
13     };
14 </script>

這樣我們自定義的withProperties可以使用在嵌套中,並且我們可以使用$parentContext來取得父上下文。

1 <div data-bind="withProperties: { displayMode: 'twoColumn' }"> 
2     The outer display mode is <span data-bind="text: displayMode"></span>. 
3     <div data-bind="withProperties: { displayMode: 'doubleWidth' }"> 
4         The inner display mode is <span data-bind="text: displayMode"></span>, but I haven't forgotten 
5         that the outer display mode is <span data-bind="text: $parentContext.displayMode"></span>. 
6     </div> 
7 </div>

通過修改綁定上下文和控制子綁定,您有一個強大的和先進的工具來創建自己的定制綁定機制。

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

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



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