knockout.js:是否更新绑定?

bnl4lu3b  于 2022-11-10  发布在  其他
关注(0)|答案(3)|浏览(236)

当我在ko.applyBindings()之后向DOM中注入任何新元素时;我可以理解为什么会发生这种情况--它们只是没有被knockout索引。
所以,一开始我以为只要在添加新元素后再次调用ko.applyBindings()就可以解决这个问题,但后来我意识到,每次调用ko.applyBindings(),相应的事件都会被触发多次。所以,在应用了五次之后,单击:绑定将被激发五次,因此这不是理想的解决方案;)
有没有类似ko.updateBindings()或其他的东西,告诉knockout,嗯...更新元素绑定?
你好,克里斯

f87krz0w

f87krz0w1#

每次调用ko.applyBindings时,都会检查整个DOM的绑定。因此,如果多次执行此操作,每个元素都会得到多个绑定。如果只想绑定一个新的DOM元素,可以将此元素作为参数传递给applyBindings函数:

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

请参阅以下相关问题:
Can you call ko.applyBindings to bind a partial view?

kxxlusnw

kxxlusnw2#

在不知道自己到底在做什么的情况下,你似乎走错了路。你的视图应该由视图模型驱动。所以你不应该直接添加DOM元素,然后需要应用敲除绑定。
相反,您应该更新视图模型以反映视图中的更改,这将导致出现新元素。
例如,对于您的$('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是否包含按钮。它所做的只是在click me可用时更新viewModel.clickMeAvailable
例如,假设click me是一个保存按钮,当表单被有效地填写时,它应该是可用的,您可以将保存按钮的可见性与formValid视图模型的可观察性联系起来。
但是当表单生效后,您决定进行更改,这样就会出现一个法律的协议,在保存之前必须同意该协议。表单的逻辑不会更改--表单生效时它仍然设置formValid。您只需要更改formValid更改时发生的情况。
正如lassombra在评论中指出的,在某些情况下,直接的DOM操作可能是最好的方法--例如,在一个复杂的动态页面中,您只想在需要的时候对视图的一部分进行水化。但是这样做会放弃Knockout提供的一些关注点分离。如果您正在考虑进行这种权衡,请注意。

sc4hvdpw

sc4hvdpw3#

我刚刚偶然发现了一个类似的问题。我试图向容器中添加新的元素,并给予那些元素一个onclick函数。
一开始我尝试了你做的事情,甚至尝试了ColinErecommended的方法。这对我来说并不是一个实用的解决方案,所以我尝试了SamStephens的方法,并得出了一个对我来说非常有效的方法:
于飞:

<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里玩它。

相关问题