将文本绑定到全局函数
Bind text to a global function
尝试将 text
绑定到视图模型外部的全局函数会引发以下错误:
knockout.js:60 Uncaught ReferenceError: Unable to process binding "foreach: function (){return names }"
Message: Unable to process binding "text: function (){return myFunction($data) }"
Message: myFunction is not defined
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.prototype.myFunction = function(){
return this + '--';
}
这是为什么?没有更好的方法将全局函数应用于 text
绑定吗?
这是我的建议,您可以按照自己的意愿行事。您的函数未在该范围内定义。在这里,您实际上将每个名称(即使它可以是一个对象)绑定到视图模型之外的函数
示例:https://jsfiddle.net/1hz10pkc/2/
HTML :
<ul data-bind="foreach: names">
<li data-bind="text:name "></li>
</ul>
JS
var myFunction = function(text){
var self = this;
self.name = text + "--" ;
}
function demoViewModel() {
var self = this;
var arr = ['a', 'b', 'c'];
self.names = ko.observableArray($.map(arr, function (element) {
return new myFunction(element);
}));
}
var mm = new demoViewModel();
ko.applyBindings(mm);
要从挖空模板中引用您的函数,需要将其附加到 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>
这并不是一个真正的 "global" 函数,它只是一个标准的 viewModel 属性,如果你最终得到了嵌套的绑定上下文,你必须做 $parents[n].myFunction
或者,如果你已经将它附加到你的根 viewModel,你可以做 $root.myFunction
.
另一种处理方法是直接将函数添加到 binding context。这允许无论当前 viewModel 是什么都可以引用它。
"foreach" 绑定处理程序和模板绑定处理程序的 "as" 选项是一种向绑定上下文添加内容的方法;但是我为此目的使用了 "let" bindingHandler,let bindingHandler 不是 KO 的官方部分,而是 often recommended 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 -->
在上面的示例中,您可以在 let
绑定中的任何位置引用 myFunction
,无论您的 viewModels 有多深。
尝试将 text
绑定到视图模型外部的全局函数会引发以下错误:
knockout.js:60 Uncaught ReferenceError: Unable to process binding "foreach: function (){return names }" Message: Unable to process binding "text: function (){return myFunction($data) }" Message: myFunction is not defined
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.prototype.myFunction = function(){
return this + '--';
}
这是为什么?没有更好的方法将全局函数应用于 text
绑定吗?
这是我的建议,您可以按照自己的意愿行事。您的函数未在该范围内定义。在这里,您实际上将每个名称(即使它可以是一个对象)绑定到视图模型之外的函数
示例:https://jsfiddle.net/1hz10pkc/2/
HTML :
<ul data-bind="foreach: names">
<li data-bind="text:name "></li>
</ul>
JS
var myFunction = function(text){
var self = this;
self.name = text + "--" ;
}
function demoViewModel() {
var self = this;
var arr = ['a', 'b', 'c'];
self.names = ko.observableArray($.map(arr, function (element) {
return new myFunction(element);
}));
}
var mm = new demoViewModel();
ko.applyBindings(mm);
要从挖空模板中引用您的函数,需要将其附加到 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>
这并不是一个真正的 "global" 函数,它只是一个标准的 viewModel 属性,如果你最终得到了嵌套的绑定上下文,你必须做 $parents[n].myFunction
或者,如果你已经将它附加到你的根 viewModel,你可以做 $root.myFunction
.
另一种处理方法是直接将函数添加到 binding context。这允许无论当前 viewModel 是什么都可以引用它。
"foreach" 绑定处理程序和模板绑定处理程序的 "as" 选项是一种向绑定上下文添加内容的方法;但是我为此目的使用了 "let" bindingHandler,let bindingHandler 不是 KO 的官方部分,而是 often recommended 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 -->
在上面的示例中,您可以在 let
绑定中的任何位置引用 myFunction
,无论您的 viewModels 有多深。