最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Adding a computed observable via the prototype to a constructor function - Stack Overflow

programmeradmin2浏览0评论

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.

发布评论

评论列表(0)

  1. 暂无评论