user1166905
user1166905

Reputation: 2622

Knockout computed not updating

I have the following in JS:

function reportCriteria(fieldId,fieldName,filterOption,optionText,filterChoice) {
        return {
            fieldId: fieldId
            fieldName: fieldName,
            filterOption: filterOption,
            optionText: optionText,
            filterChoice: filterChoice,
            description: ko.computed(function () {
                return fieldName + " which " + optionText + " " + filterChoice;
            })
        };
    }

I have an observableArray in my model that holds these which I push with: model.criteriaEntries.push(new reportCriteria(paramshere));

All looks ok until I try to edit one like so:

var criItem = ko.utils.arrayFirst(model.criteriaEntries(), function (item) {
            return item.fieldId == id;
        });
        if (criItem) {
            criItem.filterOption = option;
            criItem.optionText = opttext;
            criItem.filterChoice = choice;
            model.criteriaEntries.valueHasMutated();
        }

I get no errors and I can debug and see the object has changed but the description computed doesn't update as nothing changes on screen for the despite adding valueHasMutated?

Upvotes: 1

Views: 3619

Answers (1)

Judah Gabriel Himango
Judah Gabriel Himango

Reputation: 60051

Your problem is that you're overwriting optionText via criItem.optionText = opttext;

Don't do that. Instead, update optionText:

criItem.optionText(opttext);

Then your computed will update accordingly.


Edit Here's what your report creation code should look like:

function reportCriteria(fieldId,fieldName,filterOption,optionText,filterChoice) {
    var report = {
       fieldId: fieldI),
       fieldName: fieldName,
       filterOption: ko.observable(filterOption),
       optionText: ko.observable(optionText),
       filterChoice: ko.observable(filterChoice)
    };
    report.description = ko.computed(function () {
       return report.fieldName + " which " + report.optionText() + " " + report.filterChoice();
    });
    return report;
}

And here's how to do your editing:

var criItem = ko.utils.arrayFirst(model.criteriaEntries(), function (item) { return item.fieldId == id; });
if (criItem) {
   criItem.filterOption(option);
   criItem.optionText(opttext);
   criItem.filterChoice(choice);
}

Upvotes: 4

Related Questions