7

我正在使用 Knockout.js 2.0,我正在尝试通过添加计算的 observable 来扩展我创建的构造函数的原型,但它会抛出“self.IsSubDomain 不是函数”。我该如何解决这个错误?是否有另一种方法来扩展构造函数来解决这个问题?

http://jsfiddle.net/StrandedPirate/J44S4/3/

注意:我知道我可以在构造函数的闭包中定义计算出的 observable,但是我正在为淘汰视图模型构建一个自动代码生成器,并且我需要能够通过原型属性扩展我的对象。

4

1 回答 1

5

我也在论坛里回答了这个问题

这是一种方法(jsFiddle 示例):

<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.computed(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.com";
    }
    else {
        return this.DomainName();
   }
}; 

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

ko.applyBindings(temp);
</script>

我已经在原型中定义了函数,并在构造函数中将其作为计算的 observable。

这是一种更通用的方法(jsFiddle示例):

<div data-bind="text: fullDomainName">test</div>
<script>
Function.prototype.computed = function() {
    this.isComputed = true;
    return this;
};
Object.prototype.makeComputeds = function() {
    for (var prop in this) {
        if (this[prop] && this[prop].isComputed) {
            this[prop] = ko.computed(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.com";
    }
    else {
        return this.DomainName();
   }
}.computed();

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

ko.applyBindings(temp);
</script>

计算的底层读取函数通过原型共享,尽管实际的计算属性不会。我想如果您创建了一些对象然后更改了原型中的函数,可能会造成混淆。新对象会使用新功能,但旧对象不会。

由于计算出的 observables 是属性,因此您不应该期望能够通过原型将它们添加到现有对象中。

于 2012-04-28T02:22:02.017 回答