javascript - 如何使用子上下文可访问的自定义属性扩展模板绑定(bind)语法?

标签 javascript data-binding knockout.js templating

我正在尝试找到一种简单而优雅的方法来扩展模板绑定(bind),以便将自定义属性传播到子上下文。通过扩展,我的意思是使用具有附加属性的模板绑定(bind),而不是创建另一个绑定(bind)来控制后代绑定(bind) (controlsDescendantBindings),因为它需要另一个 DOM 元素或 KO 虚拟元素。

这是我想要实现的:

<div class="row"
     data-bind="template: {
         name: 'column-template',
         foreach: items1,
         properties: {columnType: 'col-md-6'}
     }"></div>
<div class="row"
     data-bind="template: {
         name: 'column-template',
         foreach: items2,
         properties: {columnType: 'col-md-12'}
     }"></div>

<div class="row"
     data-bind="
         template: {name: 'column-template', foreach: items1},
         properties: {columnType: 'col-md-6'}
     "></div>
<div class="row"
     data-bind="
         template: { name: 'column-template', foreach: items2},
         properties: {columnType: 'col-md-12'
     }"></div>

...使用任何变体:

<script type="text/html" id="column-template">
    <div data-bind="css : columnType">...</div>
</script>

请注意, View 模型由 2 <div class="row" /> 共享。元素,所以我不是在问如何更改 View 模型属性/可观察值。相反,我想知道是否有一种机制可以扩展 native template绑定(bind)语法以使自定义属性在子上下文中可用。

我已经阅读了一些关于扩展上下文的文档或解决方法,但找不到不需要额外 HTML 标记的解决方案:

目前,我正在使用上一个链接中建议的虚拟绑定(bind)处理程序:

ko.bindingHandlers.let = {
    init : function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        // Make a modified binding context, with extra properties, and apply it to descendant elements
        var innerContext = bindingContext.extend(valueAccessor());
        ko.applyBindingsToDescendants(innerContext, element);

        return { controlsDescendantBindings: true };
    }
};
ko.virtualElements.allowedBindings['let'] = true;

...以这种方式应用:

<!-- ko let: { displayMode: 'col-md-6' } -->
<div class="row" data-bind="template: { name: 'column-template', foreach: items1}}"></div>
<!-- /ko -->

<!-- ko let: { displayMode: 'col-md-12' } -->
<div class="row" data-bind="template: { name: 'column-template', foreach: items2}}"></div>
<!-- /ko -->

它按预期工作,但看起来有点冗长。

非常感谢!

这个问题最初是在这里问的: https://groups.google.com/forum/#!topic/knockoutjs/NvVIq72SeUY

最佳答案

如果您使用以下语法,我找到了一个解决方案:

<div class="row" data-bind="propertyTemplate: {
     name: 'column-template',
     foreach: items1,
     properties: { columnType: 'col-md-6' }
 }"></div>

与您的唯一区别是我将绑定(bind)重命名为 propertyTemplate

这是绑定(bind)代码和一个 fiddle以表明它正在工作。

ko.bindingHandlers['propertyTemplate'] = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var value = valueAccessor(),
            context = bindingContext.extend(value.properties);

        ko.applyBindingsToNode(element, { template: value }, context);

        return { 'controlsDescendantBindings': true };
    }
};

关于javascript - 如何使用子上下文可访问的自定义属性扩展模板绑定(bind)语法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20224563/

相关文章:

knockout.js - knockout - 如果日期大于则显示元素

javascript - 按下键并运行 jquery 函数

javascript - 如何在javascript中计算字符串中的数字?

c# - 无法在具有十进制绑定(bind)的文本框中输入 "."

javascript - knockout 矩阵

javascript - 可见绑定(bind)检查后 knockout 执行功能

javascript - 更改 Canvas 渐变对象的属性

javascript - 匹配 <span> 或 </span> 的正则表达式

c# - 数据绑定(bind)和跨线程异常

Knockout.js 将 JSON 对象映射到 Javascript 对象