簡體   English   中英

將文本綁定到全局功能

[英]Bind text to a global function

嘗試將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綁定嗎?

這是我建議做你想做的。 您的功能未在該范圍內定義。 在這里,您實際上將每個名稱(甚至可以是一個對象)都綁定到視圖模型之外的函數
范例: 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> 

這實際上不是一個“全局”函數,它只是一個標准的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 --> 

在上面的示例中,您可以在let綁定中的任何位置引用myFunction ,而不管您在viewModels的深處有多少級。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM