我遇到过几种情况,我必须像这样编写模板调用:
<!-- ko template: {name: 'paginatedList',
data: {listContainer: paginatedResults, itemTemplate: $parent.template}} -->
<!-- /ko -->
因为除了我的数据对象(例如paginatedResults
)之外,我还需要传递补充信息,例如用于渲染项目的模板名称。作为另一个示例,当在列表中呈现项目时,我可能需要知道存储在某个上下文中的过滤器的当前设置,该过滤器在逻辑上远离列表中的项目。
而不是必须扭曲我的数据模型(在上面的示例中,将paginatedResults
替换为{listContainer: paginatedResults, itemTemplate: $parent.template}}
,在模板上使用一些语法可以让我传递(和acccrue as templates是分层次计算的)一些深层嵌套模板在渲染时可能需要的额外上下文。
我想我想知道的是在ko.bindingHandlers
函数(init
和update
)中添加额外(可选)参数的可行性,使它们看起来像这样:
function (element,
valueAccessor,
allBindingsAccessor,
viewModel,
bindingContext,
context)
在对上面的例子进行编码时,我应该能够说出像
这样的内容<!-- ko template: {name: 'paginatedList',
data: paginatedResults,
context: {itemTemplate: $parent.template}} -->
<!-- /ko -->
或更好,
<!-- ko template: {name: 'paginatedList',
data: paginatedResults,
itemTemplate: $parent.template} -->
<!-- /ko -->
并让itemTemplate
成为我可以在嵌套模板和data-bind
属性中引用的变量。
这有意义吗?我不太了解这将是多么难以实施。我想要担心的是名称冲突,但是一些命名约定可能会绕过它。
基因
答案 0 :(得分:9)
如果不对Knockout核心进行更改,我认为您可以做的最好的是包装器绑定,它会创建一个类似于您当前传递的结构。
绑定可能如下所示:
ko.bindingHandlers.templateWithContext = {
init: ko.bindingHandlers.template.init,
update: function(element, valueAccessor, allBindings, data, context) {
var options = ko.utils.unwrapObservable(valueAccessor());
ko.utils.extend(context, options.context);
return ko.bindingHandlers.template.update.apply(this, arguments);
}
};
您可以这样称呼:
<div data-bind="templateWithContext: { name: 'itemsTmpl', data: items, context: { title: 'First' } }"></div>
以下是一个示例:http://jsfiddle.net/rniemeyer/QNvFn/
看起来您正在使用本机模板,但如果您仍在使用jQuery模板,那么它确实包含使用jQuery模板的templateOptions
功能传递的options
feature上下文数据。这在本机模板中不可用。现在的一般建议是使用$root
,$parent
和$parents
variables来访问信息或将对象作为data
传递给你在帖子中描述过。