ko.computed cannot access observables when declared inside a closure function

464 views Asked by At

I have created the following model and I don't understand why the pureComputed observable ApprovalIconCSS cannot access the Approved() observable from its function context.

function KOViewModel() {
    var self = this;
    self.IsAdding = ko.observable(false);
    self.IsEnabled = ko.observable(true);
    self.ApprovalType = ko.observable(0);

    var RowControl = function() {
        return {
            Approved: ko.observable(null),
            ApproverNotes: ko.observable(''),
            ApprovalIconCSS: ko.pureComputed(function() {
                if (this.Approved() == 0)
                    return 'glyphicon glyphicon-remove-circle';
                if (this.Approved() == 1)
                    return 'glyphicon glyphicon-ok-circle';
                if (this.Approved() == 2)
                    return 'glyphicon glyphicon-time';
                return '';
            }, this)
        };
    };

    self.RowControls = ko.observableArray([RowControl()]);
}

Appreciate if someone can shed light why the context isn't accessible. Cheers!

1

There are 1 answers

4
Retsam On BEST ANSWER

You need to call RowControls with new, and you need to attach the properties to the this object of the RowControl function, rather than returning a different object.

var RowControl = function() {
    this.Approved = ko.observable(null);
    this.ApproverNotes = ko.observable('');
    this.ApprovalIconCSS = ko.pureComputed(function() {
        if (this.Approved() == 0)
            return 'glyphicon glyphicon-remove-circle';
        if (this.Approved() == 1)
            return 'glyphicon glyphicon-ok-circle';
        if (this.Approved() == 2)
            return 'glyphicon glyphicon-time';
        return '';
    }, this)
};

self.RowControls = ko.observableArray([new RowControl()]);

The problem returning a literal object is that ko.pureComputed is being called with the this object, and if you return a different object, rather than adding properties to this, then the this object, and the result of new RowControl() (i.e. the object that has an "Approved" property) are two different objects.