创作后的淘汰赛结合

时间:2014-06-30 20:34:15

标签: javascript knockout.js

这是一个简单的观点:

<div data-bind="with: viewModel">
    <h1 data-bind="text: someproperty"></h1>

    <button data-bind="click: createNewButton">Create new Button</button>

    <div data-bind="foreach: buttons">
        <div data-bind="html: button"></div>
    </div>
</div>

JavaScript的:

var viewModel = function () {
    var self = this;

    self.someproperty = ko.observable("hi");

    self.buttons = ko.observableArray([]);

    self.createNewButton = function () {
        self.buttons.push("<button data-bind='click: doThis'></button>");
    }

    self.doThis = function () {
        console.log(this);
    }
}

ko.applyBindings({viewModel: new viewModel()});

如此有效,一旦将按钮添加到observable并更新了视图,我就想重新应用绑定。这可能吗?

1 个答案:

答案 0 :(得分:1)

你最好使用模板来解决这个问题,例如:

<script type="text/html" id="btnTemplate'>
    <button data-bind='click: $root.doThis'></button>
</script>

<div data-bind="with: viewModel">
    <h1 data-bind="text: someproperty"></h1>

    <button data-bind="click: createNewButton">Create new Button</button>

    <div data-bind="template: { name: 'btnTemplate', foreach: buttons }">
    </div>
</div>

模板引擎将自动处理绑定后代。

如果你真的必须绑定渲染后的子节点,你需要在你的foreach后写一个回调:

<div data-bind="foreach: { data: buttons, afterRender: bindNode }">
</div>

self.bindNode = function(elements, data) {
    var element = $(elements).filter('div');
    ko.applyBindingAccessorsToNode(element[0], 
       { 
           click: function() { return self.someAction } //Needs to be wrapped in a function call
       } );
}

快速查看这个JS小提琴:http://jsfiddle.net/34D6J/

我非常强烈建议通过模板(如第一个示例)或某种自定义绑定来执行此操作,否则您将遇到维护上下文和其他内容的问题。