Javascript knockout.js:更新绑定?

Javascript knockout.js:更新绑定?,javascript,knockout.js,Javascript,Knockout.js,当我在ko.applyBindings()之后向DOM中注入任何新元素时;如果被调用,那么淘汰将无法识别这些新元素。 我能理解为什么会发生这种情况——它们只是没有被敲除 所以,起初我以为在添加新元素后,只需再次调用ko.applyBindings()就可以解决这个问题,但后来我意识到,每次调用ko.applyBindings(),相应的事件都会被触发多次。因此,在应用五次之后,click:binding将触发五次,因此这不是一个理想的解决方案;) 有没有像ko.updateBindings()或

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

所以,起初我以为在添加新元素后,只需再次调用ko.applyBindings()就可以解决这个问题,但后来我意识到,每次调用ko.applyBindings(),相应的事件都会被触发多次。因此,在应用五次之后,click:binding将触发五次,因此这不是一个理想的解决方案;)

有没有像ko.updateBindings()或其他类似的东西可以告诉knockout,嗯。。。更新元素绑定

您好,
Chris

每次调用
ko.applyBindings
时,都会检查整个DOM的绑定情况。因此,如果您多次这样做,您将为每个元素获得多个绑定。如果您只想绑定一个新的DOM元素,可以将该元素作为参数传递给
applyBindings
函数:

ko.applyBindings(viewModelA, document.getElementById("newElement"));
见这一相关问题:


在不知道自己到底在干什么的情况下,你似乎走错了方向。视图应该由视图模型驱动。因此,您不应该直接添加DOM元素,然后需要对其应用敲除绑定

相反,您应该更新视图模型以反映视图中的更改,从而显示新元素

例如,对于您的
$('body').append(“”),而不是在按钮应该可见时添加DOM元素,而是使用视图模型控制按钮的可见性

因此,您的视图模型包括

var viewModel = { clickMeAvailable: ko.observable(false) }
你的HTML包括

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

当应用程序状态更改,使“单击我”按钮可用时,您只需
viewModel。单击可用(true)

这样做的目的,以及击倒的一大部分,是将业务逻辑与表示分离。因此,使click me可用的代码并不关心click me是否包含按钮。它所做的只是更新视图模型。单击我可用时,单击我可用

例如,假设click me是一个保存按钮,当有效填写表单时,该按钮应该可用。您需要将“保存”按钮的可见性绑定到
formValid
视图模型observable

但随后您决定更改内容,以便在表单有效后,出现一个法律协议,在保存之前必须获得同意。表单的逻辑没有改变-当表单有效时,它仍然设置
formValid
。您只需更改
formValid
更改时发生的情况


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

我刚刚偶然发现了一个类似的问题。我试图向容器中添加新元素,并给它们一个onclick函数

起初,你尝试了你所做的事情,甚至尝试了这种方法。这对我来说不是一个切实可行的解决方案,所以我尝试了这个方法,并提出了一个非常适合我的解决方案:

HTML:


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>

函数ViewModel(){
var self=这个;
var-id=0;
self.noderar=ko.observativearray();
self.addNode=函数(数据、事件){
self.noderr.push({
'nodeID':'node'+id,
“nodeX”:(event.offsetX-25)+“px”,
“nodeY”:(event.offsetY-10)+“px”
})
id++;
}
self.changeColor=函数(数据、事件){
event.stopPropagation();
event.target.style.color='绿色';
event.target.style.backgroundColor='白色';
}
}
应用绑定(新的ViewModel());

您可以在“我制作”中使用它。

您可以发布一些代码来显示您正在做什么吗?例如:$('body')。append('');我不确定这是否足以提供一个有用的答案。我理解您正在尝试做什么,但是如果您对代码有更全面的了解(为什么/当您注入新的DOM元素时),就很难用最好的方法来解决这个问题。在看过你目前的解决方案后,有人可能会指出一种不必注入新元素的方法,或者有一种解决方法来解决你正在尝试做的事情。看起来我已经找到了。只需调用:ko.applyBindings(viewModel);再次将所有函数绑定到整个DOM。这就是为什么在重新调用此函数后,每次回调都会被调用两次或更多次。applyBindings()的第二个参数是开始应用的DOM节点。这默认为DOM根。因此,如果要“手动”向某个DOM节点添加两个具有数据绑定属性的元素,请获取对具有新元素的DOM节点的引用,并将其作为第二个参数传递!令人惊叹的!我忘记了applyBindings()的第二个参数。是的,这也是我提出的解决方案:)遗憾的是,我没有在knockoutjs.com上找到直接的API文档,必须对ko对象进行反向工程才能找到答案--是的,没有API文档,但在更“冗长”的文档中。看看这页的一半:你确定这是答案吗?这会不会将viewModelA应用于新元素,就好像新元素是viewModelA的DOM的根一样?我可以看到它在某些甚至大多数情况下会起到什么作用,但我也可以看到它可能是产品未经检验的结果(我想)。我只是想在这里发表评论,因为我真的被一个gotcha绊倒了。我通过ajax加载子视图,并将它们粘贴到视图模型中,该视图模型绑定到视图,以将子(部分)视图放置在母版页的正确位置。人们应该非常小心它们绑定到什么元素。我不小心打了应用程序
<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>