多个组件实例会覆盖自定义绑定的回调

时间:2017-06-30 09:41:34

标签: knockout.js knockout-3.0

支持小提琴:https://jsfiddle.net/lezhnev_dmitriy/5Lvq1nra/

$(function(){

// when DOM ready

ko.bindingHandlers.button = {
  init: function (element, valueAccessor, allBindings) {
                    this.onClick = valueAccessor();
                    $(element).html('<button data-bind="click: onClick">Click</button>');
                },
  update: function (element, valueAccessor, allBindings) {
                },
};

ko.components.register('comp1', {
	template: '<div>component instance <span data-bind="text: instance_id"></span> <span data-bind="button: handleClick"></span></div>',
  viewModel: function () {
    var self = this;
    self.instance_id = ko.observable(Math.round(Math.random() * 1000)); // debug purpose

    self.handleClick = function () {
      alert('clicked at ' + self.instance_id());
    }.bind(this); // very interesting hint!
  }
});

ko.applyBindings();


});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<comp1></comp1>
<comp1></comp1>

我有两个组件,每个组件都在其模板中注入自定义绑定(button)。然后它附加一个回调绑定。 但只有最后一个绑定工作(两个按钮现在通过最后一个组件实例处理)。

我错过了什么吗?

更新: 我发现这段代码实际上会起作用

ko.bindingHandlers.button = {
                init: function (element, valueAccessor, allBindings) {
                    var self = this;
                    self.onClick = valueAccessor();
                    $(element).html('<button>Click</button>');
                    $('button', element).click(self.onClick);
                },
                update: function (element, valueAccessor, allBindings, viewModel_deprecated, bindingContext) {
                    var self = this;

                },
            };

            ko.components.register('comp1', {
                template: '<div>component instance <span data-bind="text: instance_id"></span> <span data-bind="button: handleClick"></span></div>',
                viewModel: function () {
                    var self = this;
                    self.instance_id = ko.observable(Math.round(Math.random() * 1000)); // debug purpose

                    self.handleClick = function () {
                        console.log('clicked at ' + self.instance_id());
                    }.bind(this); // very interesting hint!
                }
            });
            
ko.applyBindings();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<comp1></comp1>
<comp1></comp1>

1 个答案:

答案 0 :(得分:1)

在我看来,你不应该在bindingHandler的代码中更改DOM节点。 出于这个原因,我们有模板。

<script id="buttonTemplate" type="text/html">
    <button data-bind="click: handleClick">Click</button>
</script>    

template: '<div>component instance <span data-bind="text: instance_id"></span> <span data-bind="template: {name: \'buttonTemplate\', data: $data }"></span></div>',

我已经更新了你的小提琴:https://jsfiddle.net/5Lvq1nra/2/

编辑:实际上不需要将$ data传递到模板的data属性(默认),只是为了表明您可以将对象作为模型传递。