Javascript knockout.js 3.3-在foreach绑定中重新提交组件

Javascript knockout.js 3.3-在foreach绑定中重新提交组件,javascript,knockout.js,custom-component,knockout-3.0,Javascript,Knockout.js,Custom Component,Knockout 3.0,我的viewModel由带有可观察元素的可观察数组组成 // viewmodel var viewModel = function () { this.o = ko.observableArray(); for (var i = 0; i < 3; i++) this.o.push(ko.observable(0)); }; //视图模型 var viewModel=函数(){ this.o=ko.observearray(); 对于(变量i=0;i

我的viewModel由带有可观察元素的可观察数组组成

// viewmodel
var viewModel = function () {
    this.o = ko.observableArray();
    for (var i = 0; i < 3; i++)
    this.o.push(ko.observable(0));
};
//视图模型
var viewModel=函数(){
this.o=ko.observearray();
对于(变量i=0;i<3;i++)
这个o.push(ko.observable(0));
};
我需要更改这些元素的值。为此,我创建了组件。下面是一个简单的例子:

//custom element <component>
ko.components.register("component", {
    viewModel: function (params) {
        var self = this;
        this.value = params.value;
        console.log("init component");
        this.i = 1;
        this.change = function () {
            self.value(self.i++);
            console.log("change to " + self.value());
        }
    },
    template: "<span data-bind='text: value'></span>  <button data-bind='click:change'>Change</button>"
});
//自定义元素
ko.components.register(“组件”{
viewModel:函数(参数){
var self=这个;
this.value=params.value;
log(“init组件”);
这个。i=1;
this.change=函数(){
self.value(self.i++);
log(“更改为”+self.value());
}
},
模板:“更改”
});
此组件可以更改参数值中的可观察元素的值

我的看法很简单:

<!--ko foreach:o-->
       <component params="value: $rawData"></component>
<!--/ko-->

完整示例:
问题是,当可观测数组中的可观测元素的值发生更改时,组件将再次呈现,因为它位于foreach绑定内部。您可以在日志中看到这一点。在这种情况下,我可以使用什么样的最佳实践?谢谢

每次更改编号时都会重新创建组件,因为组件的上下文就是编号


//测试组件在foreach绑定中的工作方式
//自定义元素
ko.components.register(“组件”{
viewModel:函数(参数){
var self=这个;
this.value=params.value;
log(“init组件”);
这个。i=1;
this.change=函数(){
self.value(self.i++);
log(“更改为”+self.value());
}
},
模板:“更改”
});
//视图模型
var viewModel=函数(){
this.o=ko.observearray();
对于(变量i=0;i<3;i++)
this.o.push({myNumber:ko.observable(0)});
};
应用绑定(新的viewModel());

Knockout Repeat()是一种迭代绑定,它不创建新的绑定上下文,并且具有
foreach
模式,因此它应该可以按照您对组件的预期工作。

作为替代方法,您仍然可以传入简单值,但可以在init中创建一个新的组件viewmodel值作为可观察值。任何避免直接更改组件上下文的解决方案都将有效。感谢回复!CrimsonChris,你的解决方案迫使我改变域模型。我想避免它@Roy J,改变组件内部的可观测元素并不强制改变数组中的可观测元素。看见我的代码适用于foreach绑定之外的可观察元素,尽管上下文发生了变化。看见这是因为foreach绑定聚合了模板绑定,当上下文更改时,模板绑定会重新呈现内容。我可以停止重新提交foreach模板的内容吗?谢谢。@Tselofan可能Knockout Repeat()适合您。您可以从组件中删除状态。那么你就不必在意淘汰赛是否重拍了。小心这狂欢。1.它提供了伪可观察的$item上下文变量,该变量不是ko.subscribable。2.当您从可观察数组中删除元素时,它使用了一种奇怪的重新生成标记的算法:据我所知,它首先删除第一个DOM节点(不管已删除元素的索引如何),然后更新其余DOM节点的ko上下文。由于某些原因(可能是由于伪可下标上下文),我的组件无法处理此算法。谢谢你的回答。
<!-- ko foreach: o -->
    <component params="value: $data.myNumber"></component>
<!-- /ko -->

//Test how components work in foreach binding
//custom element <component>
ko.components.register("component", {
    viewModel: function (params) {
        var self = this;
        this.value = params.value;
        console.log("init component");
        this.i = 1;
        this.change = function () {
            self.value(self.i++);
            console.log("change to " + self.value());
        }
    },
    template: "<span data-bind='text: value'></span>  <button data-bind='click:change'>Change</button>"
});


// viewmodel
var viewModel = function () {
    this.o = ko.observableArray();
    for (var i = 0; i < 3; i++)
        this.o.push({myNumber: ko.observable(0)});
};

ko.applyBindings(new viewModel());