2012-04-23 14 views
7

Estoy usando Knockout.js 2.0 y estoy tratando de ampliar el prototipo de la función de constructor que he creado al agregar un observable calculado pero está arrojando "self" .IsSubDomain no es una función ". ¿Cómo resuelvo este error? ¿Hay alguna otra forma de extender una función constructora para resolver esto?Agregar un observable calculado a través del prototipo a una función de constructor

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

Nota: Sé que podría definir la computa observables en el interior de cierre de la función constructora, pero estoy construyendo un generador de código automatizado para modelos de vista nocaut y tengo que ser capaz de extender mis objetos a través del prototipo propiedad.

+0

Supongo que no es tan fácil. El problema es que 'computado' es una función que tiene la siguiente firma:' ko.computed (Func , Object) 'Donde Object es una ** instancia ** que se pasa al contexto' this' de la función de cálculo. – Oybek

+0

Intenté esto también pero no funcionó: 'SiteModel.prototype.fullDomainName = ko.computed (función() { \t ... }, SiteModel.prototype);' También noté que la función se está ejecutando durante carga de página que creo que es el corazón del problema. Solo debería ejecutarse después de crear una instancia del objeto. ¿Hay alguna manera de modificar el código de eliminación para evitar la ejecución de la función en este escenario? – TugboatCaptain

Respuesta

5

Yo también answered this in the forum.

Aquí hay una manera de hacerlo (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.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> 

he definido la función en el prototipo y lo hice una calculada observables en el constructor.

Aquí está una manera de hacerlo de una manera más genérica (jsFiddle example):

<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> 

El subyacente función de lectura de la computarizada se ser compartidos a través del prototipo aunque la propiedad computarizada real no lo hará. Supongo que podría haber confusión si creó algunos objetos y luego cambió la función en el prototipo. Los objetos nuevos usarían la nueva función, pero los objetos antiguos no lo harían.

Dado que las observaciones calculadas son propiedades, no debe esperar que puedan agregarlas a objetos existentes a través del prototipo.

+1

Su segundo violín podría ser una buena manera de hacerlo, pero a la derecha, no debería intentar agregar propiedades al prototipo que deberían permanecer en la función de constructor ya que serán instanciadas. – TugboatCaptain

Cuestiones relacionadas