admin管理员组

文章数量:1431317

I'm using Knockout.js 2.0 and I'm trying to extend the prototype of the constructor function I've created by adding a puted observable but its throwing up "self.IsSubDomain is not a function". How do I solve this error? Is there another way to extend a constructor function to solve this?

/

Note: I know I could define the puted observable inside the constructor function's closure but I'm building an automated code generator for knockout view models and I need to be able to extend my objects through the prototype property.

I'm using Knockout.js 2.0 and I'm trying to extend the prototype of the constructor function I've created by adding a puted observable but its throwing up "self.IsSubDomain is not a function". How do I solve this error? Is there another way to extend a constructor function to solve this?

http://jsfiddle/StrandedPirate/J44S4/3/

Note: I know I could define the puted observable inside the constructor function's closure but I'm building an automated code generator for knockout view models and I need to be able to extend my objects through the prototype property.

Share Improve this question asked Apr 23, 2012 at 22:34 TugboatCaptainTugboatCaptain 4,3384 gold badges53 silver badges86 bronze badges 2
  • I guess it is not that easily possible. The thing is that the puted is a function that has the following signature: ko.puted(Func<T>, Object) Where Object is an instance that is passed into the putation function's this context. – Oybek Commented Apr 24, 2012 at 12:35
  • I tried this too but it didn't work: SiteModel.prototype.fullDomainName = ko.puted(function () { ... }, SiteModel.prototype); I also noticed that the function is executing during page load which I think is the heart of the issue. It should only execute after an instance of the object is created. Is there a way to modify the knockout code to prevent execution of the function in this scenario? – TugboatCaptain Commented Apr 24, 2012 at 20:20
Add a ment  | 

1 Answer 1

Reset to default 5

I also answered this in the forum.

Here's one way to do it (jsFiddle example):

<div data-bind="text: fullDomainName">test</div>
<script>
function SiteModel(rootUrl, data) {
    var self = this;
    self.rootUrl = rootUrl;
    self.DomainName = ko.observable(data.DomainName);
    self.IsSubDomain = ko.observable(data.IsSubDomain);
    self.fullDomainName = ko.puted(self.fullDomainName, self);
}

SiteModel.prototype.fullDomainName = function () {
    if (this.IsSubDomain() && this.DomainName()) { // bombs out here with "self.IsSubDomain is not a function"
        return this.DomainName() + ".myCompanyWebsite.";
    }
    else {
        return this.DomainName();
   }
}; 

var temp = new SiteModel("someurl", { DomainName: "extraCool" });

ko.applyBindings(temp);
</script>

I've defined the function in the prototype and made it a puted observable in the constructor.

Here's a way to do it a more generic way (jsFiddle example):

<div data-bind="text: fullDomainName">test</div>
<script>
Function.prototype.puted = function() {
    this.isComputed = true;
    return this;
};
Object.prototype.makeComputeds = function() {
    for (var prop in this) {
        if (this[prop] && this[prop].isComputed) {
            this[prop] = ko.puted(this[prop], this, {deferEvaluation:true});
        }
    }
};

function SiteModel(rootUrl, data) {
    var self = this;
    self.rootUrl = rootUrl;
    self.DomainName = ko.observable(data.DomainName);
    self.IsSubDomain = ko.observable(data.IsSubDomain);
    self.makeComputeds();
}

SiteModel.prototype.fullDomainName = function () {
    if (this.IsSubDomain() && this.DomainName()) { // bombs out here with "self.IsSubDomain is not a function"
        return this.DomainName() + ".myCompanyWebsite.";
    }
    else {
        return this.DomainName();
   }
}.puted();

var temp = new SiteModel("someurl", { DomainName: "extraCool" });

ko.applyBindings(temp);
</script>

The underlying read function of the puted will be shared via the prototype although the actual puted property won't. I suppose there could be confusion if you created some objects and then changed the function in the prototype. New objects would use the new function, but old objects wouldn't.

Since puted observables are properties, you shouldn't expect to be able to add them to existing objects through the prototype.

本文标签: javascriptAdding a computed observable via the prototype to a constructor functionStack Overflow