zoukankan      html  css  js  c++  java
  • 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>

    通过修改绑定上下文和控制子绑定,您有一个强大的和先进的工具来创建自己的定制绑定机制。

  • 相关阅读:
    Linux设备树(四 中断)
    Linux设备树(三 属性)
    Linux设备树(二 节点)
    责任链设计模式
    获取服务器内存和可用线程
    秒杀抢购思路解析
    Hystrix 用法及注解用法
    object is not an instance of declaring class
    sqlserver 截取字符串
    sqlserver 转化函数
  • 原文地址:https://www.cnblogs.com/wukong65/p/2807674.html
Copyright © 2011-2022 走看看