• KnockoutJS 3.X API 第五章 高级应用(2) 控制后代绑定


    注意:这是一种高级技术,通常仅在创建可重用绑定的库时使用。

    默认情况下,绑定仅影响它们应用到的元素。 但是如果你想影响所有的后代元素呢?

    为此,只需从绑定的init函数中返回{controlsDescendantBindings:true}即可。

    示例1:控制是否应用后代绑定

    对于一个非常简单的例子,这里有一个名为allowBindings的自定义绑定,允许后代绑定仅当它的值为true时才应用。 如果值为false,则allowBindings告诉Knockout它负责后代绑定,因此它们不会像往常一样绑定。

    ko.bindingHandlers.allowBindings = {
        init: function(elem, valueAccessor) {
            // Let bindings proceed as normal *only if* my value is false
            var shouldAllowBindings = ko.unwrap(valueAccessor());
            return { controlsDescendantBindings: !shouldAllowBindings };
        }
    };

    要使此效果生效,以下是一个示例用法:

    <div data-bind="allowBindings: true">
        <!-- This will display Replacement, because bindings are applied -->
        <div data-bind="text: 'Replacement'">Original</div>
    </div>
     
    <div data-bind="allowBindings: false">
        <!-- This will display Original, because bindings are not applied -->
        <div data-bind="text: 'Replacement'">Original</div>
    </div>

    示例2:为子孙绑定提供附加值

    通常,使用controlsDescendantBindings的绑定也将调用ko.applyBindingsToDescendants(someBindingContext,element)来对一些修改的绑定上下文应用后代绑定。 例如,您可以使用一个名为withProperties的绑定将一些额外的属性附加到绑定上下文,然后可用于所有后代绑定:

    ko.bindingHandlers.withProperties = {
        init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
            // Make a modified binding context, with a extra properties, and apply it to descendant elements
            var innerBindingContext = bindingContext.extend(valueAccessor);
            ko.applyBindingsToDescendants(innerBindingContext, element);
     
            // Also tell KO *not* to bind the descendants itself, otherwise they will be bound twice
            return { controlsDescendantBindings: true };
        }
    };

    正如你可以看到,绑定上下文有一个扩展函数,产生一个带有额外属性的克隆。 extend函数接受具有要复制的属性的对象或返回此类对象的函数。 函数语法是首选的,以便将来在绑定值中的更改始终在绑定上下文中更新。 此过程不会影响原始绑定上下文,因此不会影响同级元素的危险 - 它只会影响后代。

    以下是使用上述自定义绑定的示例:

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

    示例3:在绑定上下文层次结构中添加额外的级别

    绑定(如with和foreach)在绑定上下文层次结构中创建额外的级别。 这意味着它们的后代可以通过使用$ parent,$ parents,$ root或$ parentContext来访问外部级别的数据。

    如果你想在自定义绑定中这样做,那么不使用bindingContext.extend(),使用bindingContext.createChildContext(someData)。 这返回一个新的绑定上下文,其viewmodel是someData,其$ parentContext是bindingContext。 如果需要,您可以使用ko.utils.extend扩展具有额外属性的子上下文。 例如,

    ko.bindingHandlers.withProperties = {
        init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
            // Make a modified binding context, with a extra properties, and apply it to descendant elements
            var childBindingContext = bindingContext.createChildContext(
                bindingContext.$rawData, 
                null, // Optionally, pass a string here as an alias for the data item in descendant contexts
                function(context) {
                    ko.utils.extend(context, valueAccessor());
                });
            ko.applyBindingsToDescendants(childBindingContext, element);
     
            // Also tell KO *not* to bind the descendants itself, otherwise they will be bound twice
            return { controlsDescendantBindings: true };
        }
    };

    这个更新的withProperties绑定现在可以以嵌套方式使用,每个嵌套级别都可以通过$ parentContext访问父级别:

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

    通过修改绑定上下文和控制后代绑定,一个强大的和高级的工具来创建自己的自定义绑定机制。

  • 相关阅读:
    Nginx之常用操作
    linux之信息查看
    KPI VS OKR
    python之jupyter安装与使用
    python进阶资源
    python之排序(sort/sorted)
    python之文件操作
    远程连接工具
    docker之本地连接
    Windows服务器连接
  • 原文地址:https://www.cnblogs.com/smallprogram/p/5968616.html
Copyright © 2020-2023  润新知