2014-10-29 30 views
2

從淘汰賽文檔:knockoutjs custum綁定預處理方法和addBindingCallback?

ko.bindingHandlers.<name>.preprocess(value, name, addBindingCallback)

參數

:...
:...
addBinding:您可以選擇使用回調函數在當前元素上插入另一個綁定。這需要兩個參數,名稱和值。例如,在預處理函數中,調用addBinding('visible', 'acceptsTerms()');以使Knockout的行爲與該元素上綁定了visible: acceptsTerms()一樣。

例如,我們可以有這樣的綁定:

ko.bindingHandlers.live = { 
    preprocess: function (str, name, addBindingCallback) { 
     addBindingCallback('value', str); 
     addBindingCallback('valueUpdate', "'afterkeydown'") 
    } 
}; 
// Or 
ko.bindingHandlers.log = { 
    preprocess: function (str, name, addBindingCallback) { 
     addBindingCallback('click', "function(){console.log('test');}"); 
    } 
}; 

我的問題:
是否有可能通過preporcess方法的新添加的綁定範圍內的變量?

ko.bindingHandlers.log = { 
    preprocess: function (str, name, addBindingCallback) { 
     // an object which is not in my viewmodel and context 
     var $scoped_obj = get_from_some_external_service(str); 
     // i want to pass `$scoped_obj` to the newly added click binding 
     addBindingCallback('click', "function(){console.log($scoped_obj);}"); 
    } 
}; 

這可能嗎?如何 ?

+0

我不認爲這應該是你應該努力做的事情,至少在預處理調用中。 「preprocess」調用中發生的事情應該是你可以直接添加到你的視圖恕我直言的東西。如果你正在進行計算,那麼這些計算應該通過視圖模型完成,否則直接在綁定處理程序中完成。 – 2014-10-29 22:25:06

回答

4

您現在正在嘗試的方式不行,因爲點擊處理程序是由Function評估的,該處理程序接受字符串作爲函數體。範圍在那個時候丟失了。

你可以做的是創造出你的點擊處理程序中調用靜態函數:

ko.bindingHandlers.log = { 
    functions: [], 
    preprocess: function (str, name, addBindingCallback) { 
     var fnIndex = ko.bindingHandlers.log.functions.length; 

     var $scoped_obj = {a: 'b'}; 
     ko.bindingHandlers.log.functions.push(function() { 
      console.log($scoped_obj); 
     }); 
     addBindingCallback('click', "ko.bindingHandlers.log.functions["+fnIndex+"]"); 
    } 
}; 

http://jsfiddle.net/fpoeeb7L/

另外,您可以使用ko.toJSON創建點擊處理程序中的變量:

ko.bindingHandlers.log = { 
    preprocess: function (str, name, addBindingCallback) { 
     var $scoped_obj = {a: 'b'}; 
     addBindingCallback('click', "function() { var $scoped_obj = " + ko.toJSON($scoped_obj) + "; console.log($scoped_obj); }"); 
    } 
}; 

請參閱http://jsfiddle.net/5e5jbuum/

但是如果$scoped_obj包含函數,這將不起作用。

1

您可以使用自執行函數爲範圍變量創建閉包。使用封閉創建範圍的變量,並使用它的功能,並返回功能,像這樣:

preprocess: (function() { 
    var $scoped_obj = get_from_some_external_service(str); 
    var fn = function(str, name, addBindingCallback) { 
     // can use the scoped variable 
    }; 
    return fn; 
})(); // self-execution 

然而,考慮到傑夫·梅爾卡多對你的問題發表評論。