js:更新绑定

knockout.js: update bindings?

本文关键字:绑定 更新 js      更新时间:2023-09-26

当我在ko.applyBindings()之后向DOM注入任何新元素时;被调用,那么淘汰赛将无法识别这些新元素。我可以理解为什么会发生这种情况——它们只是没有被knockout索引。

所以,起初我认为这将通过添加新元素后再次调用ko.applyBindings()来解决,但后来我意识到,对于您所做的每个ko.applyBindings()调用,相应的事件被多次触发。因此,在应用五次之后,click: binding将被触发五次,所以这不是一个理想的解决方案;)

是否有像ko.updateBindings()或其他东西,告诉knockout,嗯…更新元素绑定?

问候,克里斯。

每次调用ko.applyBindings时,将检查整个DOM是否存在绑定。因此,如果您多次执行此操作,您将为每个元素获得多个绑定。如果你只是想绑定一个新的DOM元素,你可以把这个元素作为参数传递给applyBindings函数:

ko.applyBindings(viewModelA, document.getElementById("newElement"));

参见以下相关问题:

你能打电话给我吗?applyBindings绑定一个局部视图?

如果不知道你到底在做什么,你似乎走错了路。视图应该由视图模型驱动。所以你不应该直接添加DOM元素,因为你需要对。

应用knockout绑定。

相反,您应该更新您的视图模型以反映视图中的更改,这将导致您的新元素出现。

所以,例如,对于你的$('body').append('<a href="#" data-bind="click: something">Click me!</a>');,而不是添加DOM元素时,按钮应该是可见的,控制按钮的可见性使用视图模型。

你的视图模型包含

var viewModel = { clickMeAvailable: ko.observable(false) }

你的HTML包含

<a href="#" data-bind="click: something, visible: clickMeAvailable">Click me!</a>

当应用程序状态改变时,点击我按钮可用,然后您只需viewModel.clickMeAvailable(true)

这样做的重点是将业务逻辑从表示中分离出来,这也是knockout的一个重要部分。让click me可用的代码并不关心click me是否包含一个按钮。它所做的只是在点击我可用时更新viewModel.clickMeAvailable

例如,说click me是一个保存按钮,当表单被有效填写时应该可用。你可以将保存按钮的可见性绑定到formValid视图模型的可观察对象。

但是当你决定改变一些事情,所以在表格有效之后,一个法律协议出现了,在保存之前必须同意。你的形式的逻辑没有改变-它仍然设置formValid时,形式是有效的。您只需更改formValid更改时发生的情况。

正如lassombra在这个回答的评论中指出的那样,在某些情况下,直接DOM操作可能是您的最佳方法——例如,在一个复杂的动态页面中,您只希望在需要时填充视图的部分。但是这样做就放弃了Knockout提供的一些关注点分离。如果您正在考虑做出这种权衡,请注意。

我偶然发现了一个类似的问题。我试图添加新的元素到容器,并给那些onclick功能。

起初尝试了你所做的事情,甚至尝试了ColinE推荐的方法。这对我来说不是一个实用的解决方案,所以我尝试了SamStephens的方法,并提出了这个方法,它对我来说非常有效:

HTML:

<div id="workspace" data-bind="foreach:nodeArr, click:addNode">
<div class="node" data-bind="attr:{id:nodeID},style:{left:nodeX,top:nodeY},text:nodeID, click:$parent.changeColor"></div>
</div>
JavaScript:

<script>
function ViewModel() {
var self = this;
var id = 0;
self.nodeArr = ko.observableArray();
self.addNode = function (data, event) {
    self.nodeArr.push({
        'nodeID': 'node' + id,
        'nodeX' : (event.offsetX - 25) + 'px',
        'nodeY' : (event.offsetY - 10) + 'px'
    })
    id++;
}
self.changeColor = function(data, event){
    event.stopPropagation();
    event.target.style.color = 'green';
    event.target.style.backgroundColor = 'white';
}
}
ko.applyBindings(new ViewModel());
</script>

你可以在我制作的JS Fiddle中使用它