试图绑定text
到视图模型外部的全局函数会引发以下错误:
kickout.js:60未捕获ReferenceError:无法处理绑定“ foreach:function(){返回名称}”消息:无法处理绑定“ text:function(){return myFunction($ data)}”消息:未定义myFunction
的HTML
<ul data-bind="foreach: names">
<li data-bind="text: myFunction($data)"></li>
</ul>
JS
function myFunction(text){
return text + '--';
}
function demoViewModel() {
self.names = ['a', 'b', 'c'];
return self;
}
var mm = new demoViewModel();
ko.applyBindings(mm);
相反,如果我String
以以下方式扩展对象并应用该函数,则它将按预期工作:
<li data-bind="text: $data.myFunction()"></li>
扩展String对象:
String.prototype.myFunction = function(){
return this + '--';
}
为什么是这样?没有更好的方法将全局函数应用于text
绑定吗?
要从敲除模板中引用您的函数,需要将其附加到ViewModel。在上面的简单情况下,您可以将其附加到demoViewModel
模板中并直接在模板中引用它:
function myFunction(text){
return text + '--';
}
function demoViewModel() {
var self = this;
self.names = ['a', 'b', 'c'];
self.myFunction = myFunction;
return self;
}
ko.applyBindings(new demoViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul data-bind="foreach: names">
<li data-bind="text: myFunction($data)"></li>
</ul>
这并不是一个真正的“全局”函数,它只是一个标准的viewModel属性,如果最终遇到了嵌套的绑定上下文,$parents[n].myFunction
或者必须将其附加到根viewModel上,就可以这样做$root.myFunction
。
处理此问题的另一种方法是将函数直接添加到绑定上下文中。这使得无论当前viewModel是什么,都可以对其进行引用。
“ foreach”绑定处理程序和模板绑定处理程序上的“ as”选项是将内容添加到绑定上下文中的一种方法。但是我为此目的使用了一个“ let”的bindingHandler,let bindingHandler不是KO的正式组成部分,但经常被核心贡献者之一迈克尔·贝斯特(Michael Best)推荐。
function myFunction(text){
return text + '--';
}
function demoViewModel() {
var self = this;
self.names = ['a', 'b', 'c'];
self.myFunction = myFunction;
return self;
}
//Let binding Handler
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.applyBindings(new demoViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<!-- ko let: {
myFunction: myFunction
} -->
<ul data-bind="foreach: {
data: names,
at: 'name'
}">
<li data-bind="text: myFunction($data)"></li>
</ul>
<!-- /ko -->
在上面的示例中,您可以引用绑定中的myFunction
任何位置let
,而不管您在viewModels的深处有多少级。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句