Hay un par de ventajas al usar una función para definir su modelo de vista.
La principal ventaja es que tiene acceso inmediato a un valor de this
que es igual a la instancia que se está creando. Esto significa que usted puede hacer:
var ViewModel = function(first, last) {
this.first = ko.observable(first);
this.last = ko.observable(last);
this.full = ko.computed(function() {
return this.first() + " " + this.last();
}, this);
};
lo tanto, su observables computarizada se puede unir al valor apropiado de this
, incluso si llama desde un ámbito diferente.
Con un objeto literal, que tendría que hacer:
var viewModel = {
first: ko.observable("Bob"),
last: ko.observable("Smith"),
};
viewModel.full = ko.computed(function() {
return this.first() + " " + this.last();
}, viewModel);
En ese caso, se puede usar viewModel
directamente en la observables computarizada, pero se vuelve evaluado inmediata (por defecto) por lo que no podía defínalo en el literal del objeto, ya que viewModel
no está definido hasta después de que se cierra el literal del objeto. A muchas personas no les gusta que la creación de su modelo de vista no esté encapsulada en una sola llamada.
Otro patrón que puede utilizar para asegurarse de que this
sea siempre apropiado es establecer una variable en la función igual al valor apropiado de this
y usarlo en su lugar. Esto sería como:
var ViewModel = function() {
var self = this;
this.items = ko.observableArray();
this.removeItem = function(item) {
self.items.remove(item);
}
};
Ahora, si usted está en el alcance de un elemento individual y llamar $root.removeItem
, el valor de this
serán realmente los datos que se están ligados a ese nivel (lo que sería el elemento). Al usar self en este caso, puede asegurarse de que se elimine del modelo de vista general.
Otra opción es usar bind
, que es compatible con navegadores modernos y agregado por KO, si no es compatible. En ese caso, se vería como:
var ViewModel = function() {
this.items = ko.observableArray();
this.removeItem = function(item) {
this.items.remove(item);
}.bind(this);
};
hay mucho más que se puede decir sobre este tema y muchos patrones que se puede explorar (como patrón de módulo y el diseño del módulo revelador), pero básicamente usando una función da tiene más flexibilidad y control sobre cómo se crea el objeto y la capacidad de referenciar variables que son privadas para la instancia.
No creo que haya una diferencia. Usualmente uso el patrón de constructor, ya que a menudo tengo métodos que prefiero declarar en el 'prototipo' (métodos que a menudo, por ejemplo, captan datos del servidor y actualizan el modelo de vista en consecuencia). Sin embargo, todavía podría declararlos como propiedad de un objeto literal, por lo que realmente no puedo ver la diferencia. –
Esto no tiene nada que ver con knockout, y todo tiene que ver con facilidad de instanciación de objetos personalizados en JavaScript – zzzzBov
@Kev si el viewModel es una función constructora, se escribe en UpperCase como var PersonViewModel = function() {...} ; – Elisabeth