Are computed observables on prototypes feasible in KnockoutJS?

╄→尐↘猪︶ㄣ 提交于 2019-12-05 05:57:39

You mention that you don't want to have an instance of the ko.computed function on each instance of your javascript class, however, that won't really work with how ko's functionality has been built. When you use ko.computed or ko.observable they create specific memory pointers to private variables inside that you would not normally want to be shared across class instances (although in rare cases you might).

I do something like this:

var Base = function(){
    var extenders = [];

    this.extend = function(extender){
        extenders.push(extender);
    };

    this.init = function(){
        var self = this; // capture the class that inherits off of the 'Base' class

        ko.utils.arrayForEach(extenders, function(extender){

             // call each extender with the correct context to ensure all
             // inheriting classes have the same functionality added by the extender
             extender.call( self );
        });
    };
};

var MyInheritedClass = function(){
    // whatever functionality you need

   this.init(); // make sure this gets called
};

// add the custom base class
MyInheritedClass.prototype = new Base();

then for the computed observables (which HAVE to be instance functions on each instance of your MyInheritedClass) I just declare them in an extender like so:

MyInheritedClass.prototype.extend(function(){

     // custom functionality that i want for each class 
     this.something = ko.computed(function() {
         return 'test';
     });
});

Given your example and the Base class defined above, you could easily do:

var Item = function(data) {
    var item = this;

    ko.mapping.fromJS(data, mapping, item);

    this.init(); // make sure this gets called
};
Item.prototype = new Base();

Item.prototype.extend(function () {
    var self = this;

    this.Points = ko.computed(function () {

        // PointsFromUser may be 0, so only ignore it if the value is undefined/null
        return (self.PointsFromUser != null) ? 
               self.PointsFromUser : self.PointsCalculated;
    });
};

Then all instances of your Item class will have a Points property, and it will correctly handle the ko.computed logic per instance.

Item.prototype.Points = function () {
var item = this;
return ko.computed(function () {
    // PointsFromUser may be 0, so only ignore it if the value is undefined/null
    return (item.PointsFromUser != null) ? item.PointsFromUser : item.PointsCalculated;
});

};

Item.prototype.extend(function () {
var scope = this
this.Points = ko.computed(function () {
    return (this.PointsFromUser != null) ? 
           this.PointsFromUser : this.PointsCalculated;
}, scope);
};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!