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

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

为此,只需从绑定的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>

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

KnockoutJS 3.X API 第五章 高级应用(2) 控制后代绑定的更多相关文章

  1. KnockoutJS 3.X API 第五章 高级应用(3) 虚拟元素绑定

    注意:这是一种高级技术,通常仅在创建可重用绑定的库时使用. 这不是你通常需要做的时候使用Knockout构建应用程序. Knockout的控制流绑定(例如,if和foreach)不仅可以应用于常规DO ...

  2. KnockoutJS 3.X API 第五章 高级应用(1) 创建自定义绑定

    您不仅限于使用内置的绑定,如click,value绑定等,您可以创建自己的绑定. 这是如何控制视图模型如何与DOM元素进行交互,并且为您提供了大量的灵活性,以便于以复用的方式封装复杂的行为. 注册绑定 ...

  3. KnockoutJS 3.X API 第五章 高级应用(5) 使用预处理扩展Knockout绑定语法

    注意:这是一种高级技术,通常仅在创建可重用绑定或扩展语法的库时使用. 这不是你通常需要做的时候使用Knockout构建应用程序. 从Knockout 3.0开始,开发人员可以通过提供在绑定过程中重写D ...

  4. KnockoutJS 3.X API 第五章 高级应用(4) 自定义处理逻辑

    在典型的Knockout应用程序中,DOM元素是动态添加和删除的,例如使用模板绑定或通过控制流绑定(if,ifnot,with和foreach). 当创建自定义绑定时,通常需要添加清除逻辑,当Knoc ...

  5. KnockoutJS 3.X API 第四章 数据绑定(1) 文本及样式绑定

    目录 本节将介绍六种文本绑定方式: visible绑定 text绑定 html绑定 css绑定 style绑定 attr绑定 可见文本绑定(visible) 使用visible绑定,来控制DOM元素的 ...

  6. KnockoutJS 3.X API 第四章(14) 绑定语法细节

    data-bind绑定语法 Knockout的声明性绑定系统提供了一种简洁而强大的方法来将数据链接到UI. 绑定到简单的数据属性或使用单个绑定通常是容易和明显的. 对于更复杂的绑定,它有助于更好地了解 ...

  7. KnockoutJS 3.X API 第三章 计算监控属性(5) 参考手册

    计算监控属性构造参考 计算监控属性可使用以下形式进行构造: ko.computed( evaluator [, targetObject, options] ) - 这种形式是创建一个计算监控属性最常 ...

  8. KnockoutJS 3.X API 第七章 其他技术(7) 微任务

    注意:本文档适用于Knockout 3.4.0及更高版本. Knockout的微任务队列 Knockout的微任务队列支持调度任务尽可能快地运行,同时仍然是异步的,努力安排它们在发生I / O,回流或 ...

  9. KnockoutJS 3.X API 第六章 组件(5) 高级应用组件加载器

    无论何时使用组件绑定或自定义元素注入组件,Knockout都将使用一个或多个组件装载器获取该组件的模板和视图模型. 组件加载器的任务是异步提供任何给定组件名称的模板/视图模型对. 本节目录 默认组件加 ...

随机推荐

  1. Oracle查看用户操作sql语句以及数据库日志

    --查看日志文件 select member from v$logfile; --查看表空间使用情况 SELECT SUM(bytes) / (1024 * 1024) AS free_space, ...

  2. 命令安装VS

     Installing Visual Studio Visual Studio 2015   Other Versions Visual Studio 2013 Visual Studio 2010 ...

  3. 关于webapp的一点思考

    早上上班路上碰到发传单推广app的小MM被上司训斥,忽然想起一个问题,现在的nativeapp推广成本到底多高?能不能用浏览器访问app的方式降低这个成本. 现在很多app采用壳+web内容的方式,但 ...

  4. new的原罪

    一直以为在开发阶段能够直接调用的,速度而言一定是最优秀的,因为总比后期通过反射之类来调用来得快吧. 下面请看一个SB的例子,重新编译以后,这个类在创建100,000,000实体时居然耗费了16秒的时间 ...

  5. leetcode sort List

    Sort a linked list in O(n log n) time using constant space complexity. /** * Definition for singly-l ...

  6. i18n国际化

    <%  request.setAttribute("date", new Date());  request.setAttribute("salary", ...

  7. JS写的排序算法演示

    看到网上有老外写的,就拿起自已之前完成的jmgraph画图组件也写了一个.想了解jmgraph的请移步:https://github.com/jiamao/jmgraph 当前演示请查看:http:/ ...

  8. Jexus针对Asp.net core应用程序的六大不可替代的优势

    1,配置简便:在Jexus上,Asp.net core只是Jexus上的一个"站点",因此,只需在Jexus上配置这个站点就行,无需其它配置: 2,操作统一:Jexus停止这个站点 ...

  9. EmberJs之数组绑定@each&[]

    写在前面 好长时间没有写博客了,昨天花了些时间又整理了下之前发布过的<Ember.js之computed Property>文章,并创建了一个测试代码库,花了些时间,希望能使用测试代码的方 ...

  10. Java多线程2:Thread中的实例方法

    Thread类中的方法调用方式: 学习Thread类中的方法是学习多线程的第一步.在学习多线程之前特别提出一点,调用Thread中的方法的时候,在线程类中,有两种方式,一定要理解这两种方式的区别: 1 ...