动态添加的Knockout数据绑定属性不会触发click事件处理程序

时间:2014-03-04 22:19:28

标签: knockout.js

在我的viewmodel的viewAttached事件中,我创建了一个动态锚元素,如下所示:

 qaItemLink = document.createElement("a");
 $(qaItemLink).attr({ 'class': 'qaTreeItem', 'href': '#', 'data-bind': 'click:$root.showQaItemDetails' });

在UI中检查时呈现如下:

<a class="qaTreeItem" href="#" data-bind="click:$root.showQaItemDetails">Item 1</a>

我没有看到正在渲染的锚标记有任何问题。可能是什么原因导致函数showQaItemDetails没有被调用?

2 个答案:

答案 0 :(得分:6)

如果在调用ko.applyBindings之后添加了元素,那么Knockout就没有机会绑定它。如果您使用template绑定(或withforeach等)来添加动态内容,那么Knockout会为您解决此问题。这通常是最好的方法。

在您的情况下,如果可能,您可以等到ko.applyBindings,直到内容被添加为止。

您也可以通过调用ko.applyBindings(viewModel, element)直接绑定元素。这将绑定元素及其子元素。但是,我不知道你的锚需要绑定什么上下文(root与某些嵌套项)。

也可以使用ko.applyBindingsToNode(或3.0 ko.applyBindingAccessorsToNode传递返回绑定的函数)直接应用绑定,如:

ko.applyBindingsToNode(qaItemLink, { click: viewModel.showQaItemDetails }, optionalContext);

答案 1 :(得分:0)

我对durandal不太了解,所以这可能不合适......但最好的淘汰方法是避免在你的viewmodels中使用jQuery,而是编写knockout模板或数据绑定来进行dom操作。如果由于某种原因你不能使用淘汰模板,rp-niemeyer就是现货。我为你制作了一个人为的例子。

function MapItem(item) {
    item.Name = ko.observable(item.Name);
}
function viewmodel(serverItems) { 
    var self = this;
    self.Items = ko.observableArray(ko.utils.arrayMap(serverItems,MapItem))
    self.SelectedItem = ko.observable(null)
    self.SelectItem = function(item) {
        self.SelectedItem(item);
    }

}

使用这样的模板

<div class="view">
    <ul data-bind="foreach:Items">
        <li><a href="#" data-bind="text:Name,click:$root.SelectItem"></a></li>
    </ul>
    <div class="SelectedItemContainer" >
        <p data-bind="visible:SelectedItem() == null">Select an item from the list</p>
        <div class="SelectedItem" data-bind="with:SelectedItem">
          <h1 data-bind="text:Name"></h1>
          <input type="text" data-bind="value:Name" />
        </div>
    </div>
</div>