Knockout.js Computed not Displayed Upon User Selection

37 Views Asked by At

I have a table, where each row is bound to a Knockout.js model:

foreach: treatmentsOptions

I would like for the user to be able to click on an "Add" button in each table row, and for that to be colored differently, and there can be multiple added rows. I thought I'd do it by assigning a value to model property named IsSelected, and then use style binding.

I have this code, that seems to work, but obviously isn't filtered based on what I want:

self.treatmentsOptions = ko.computed(function () { _dummyObservable();

var is_linked = $.map(self.treatments(), function (obj) {
    for (var i = 0; i < self.linkedItems().length; i++) {
        if (self.linkedItems()[i].PriceListItemId() == obj.Id())
            return obj.Id();
    }
});

for (var i = 0 ; i < self.treatments().length ; i++) {

    self.treatments()[i].IsSelected = ko.observable(false);

    if (i % 2 == 0) {
        self.treatments()[i].IsSelected = ko.observable(true);
    }
    else {
        self.treatments()[i].IsSelected = ko.observable(false);
    }
}


var options = self.treatments();
return options;

});

Now, what I want is that whenever the user clicks on "Add", and this computed is triggered, that the following code will work:

self.treatmentsOptions = ko.computed(function () {
    _dummyObservable();

    var is_linked = $.map(self.treatments(), function (obj) {
        for (var i = 0; i < self.linkedItems().length; i++) {
            if (self.linkedItems()[i].PriceListItemId() == obj.Id())
                return obj.Id();
        }
    });

    for (var i = 0 ; i < self.treatments().length ; i++) {

        self.treatments()[i].IsSelected = ko.observable(false);

        if (is_linked.includes(parseInt(self.treatments()[i].Id()))) {
            self.treatments()[i].IsSelected = ko.observable(true);
        }
        else {
            self.treatments()[i].IsSelected = ko.observable(false);
        }
    }


    var options = self.treatments();
    return options;

});

I would like each table row to be colored. What am I missing here?

1

There are 1 best solutions below

1
On

You set ko.observables by calling them with a value. This code block looks very suspicious:

// Don't do this:
self.treatments()[i].IsSelected = ko.observable(false);

if (i % 2 == 0) {
    self.treatments()[i].IsSelected = ko.observable(true);
}
else {
    self.treatments()[i].IsSelected = ko.observable(false);
}

It should probably be replaced by:

self.treatments()[i].IsSelected(i % 2 === 0);

Note that rows of alternating color can be styled in css by using the nth-child(odd) and nth-child(even) selectors.

You can also use the $index property in the binding context of a foreach binding.