knockoutjs custum bindings预处理方法& addBindingCallback?

时间:2014-10-29 21:22:30

标签: javascript knockout.js knockout-3.0

来自淘汰赛文件:

  

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);}");
   }
};

这可能吗?怎么样?

2 个答案:

答案 0 :(得分:4)

你现在尝试它的方式,你不能,因为点击处理程序由Function评估,它接受一个字符串作为函数体。范围在那时失去了。

你可以做的是创建一个静态函数,你可以在click处理程序中调用它:

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 :(得分: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

但是,请考虑Jeff Mercado对您的问题的评论。