Knockout.js 3.3 - render component in foreach binding

My viewModel consists of an observable array with observable items.

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

      

I need to change the values โ€‹โ€‹of these elements. And for this I create a component. Simple example:

//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>"
});

      

This component can change the value of an observable element that is included in params.value.

My view is very simple:

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

      

Full example: http://jsfiddle.net/tselofan/xg16u5cg/7/ The problem is when the value of the observable in the observable array changes, the component is rendered again as it is inside the foreach binding. You can see this in the magazines. What is the best practice I can use in this situation? Thanks you

+3


source to share


2 answers


The component is re-created every time the number changes, because the component context is a number.

http://jsfiddle.net/Crimson/xg16u5cg/8/



<!-- 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());

      

+1


source


Knockout-Repeat ( https://github.com/mbest/knockout-repeat ) is an iterative binding that does not create a new binding context and has a mode foreach

, so it should work as you expect with your component.



+1


source







All Articles