jinxed_coder
jinxed_coder

Reputation: 39

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

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!

Upvotes: 1

Views: 452

Answers (1)

Retsam
Retsam

Reputation: 33389

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.

Upvotes: 1

Related Questions