Tengo una serie de elementos que regresan del servicio. Intento definir un observable calculado para cada instancia de Item, por lo que mi instinto me dice que lo coloque en el prototipo.¿Son factibles los observables calculados en prototipos en KnockoutJS?
Un caso para el observable calculado: el sistema calcula puntos, pero el usuario puede elegir anular el valor calculado. Necesito mantener el valor calculado disponible en caso de que el usuario elimine la anulación. También necesito unir puntos asignados por el usuario y calculados, y sumar los totales.
estoy usando mapeo de hacer lo siguiente:
var itemsViewModel;
var items = [
{ 'PointsCalculated' : 5.1 },
{ 'PointsCalculated' : 2.37, 'PointsFromUser' : 3 }
];
var mapping = {
'Items' : {
create : function(options) {
return new Item(options.data);
}
}
};
var Item = function(data) {
var item = this;
ko.mapping.fromJS(data, mapping, item);
};
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;
});
};
ko.mapping.fromJS(items, mapping, itemsViewModel);
La forma en que funciona ahora, tengo que llamar a la función anónima para devolver la observables computarizada. Eso parece crear una nueva instancia de la observable calculada para cada enlace, que derrota la mayor parte del punto de ponerlo en el prototipo. Y es un poco molesto tener que descifrar cuántos paréntesis usar cada vez que accedo a un observable.
También es algo frágil. Si intento acceder Puntos() en el código, no puedo hacer
var points = 0;
var p = item.Points;
if (p && typeof p === 'function') {
points += p();
}
debido a que los cambios en el contexto de los puntos() para DOMWindow, en lugar de elemento.
Si pongo el calculado en create() en la asignación, podría capturar el contexto, pero luego hay una copia del método en cada instancia de objeto.
Encontré la publicación de Grupos de Google de Michael Best (http://groups.google.com/group/knockoutjs/browse_thread/thread/8de9013fb7635b13). El prototipo devuelve un nuevo observable calculado en "activar". No he descubierto lo que se llama "activar" (¿tal vez Objs?), Pero supongo que todavía sucede una vez por objeto, y no tengo ni idea de qué alcance 'obtendrá'.
En este punto, creo que ya supero lo que está disponible en los documentos publicados, pero todavía estoy trabajando para descifrar lo que está pasando desde la fuente.
Gracias. Creo que el objetivo de .extend() es simplemente hacer clic. Esto resuelve mis problemas de invocación de alcance/función doble muy bien, y tomaré su palabra de que Knockout no me permitirá mantener la observación computable real en el prototipo. –
eric, ¿podría proporcionar una versión más "azucarada"? Algo como childClass = BaseClass.extend (function() {/*...*/}) que ya hace la configuración de la cadena del prototipo? Tener que hacerlo manualmente para cada instancia de clase es un poco extraño ... – fbuchinger
No veo ningún motivo por el que no se pueda poner una función estática 'extender' en el Constructor heredado, siempre y cuando básicamente lo haga: ' SubClass.extend = function (extensor) {SubClass.prototype.extend (extensor); }; ' – ericb