En knockout js veo Ver modelos declarados como:
var viewModel = {
firstname: ko.observable("Bob")
};
ko.applyBindings(viewModel );
o:
var viewModel = function() {
this.firstname= ko.observable("Bob");
};
ko.applyBindings(new viewModel ());
¿Cuál es la diferencia entre los dos, si hay alguno?
Encontré esta discusión en el grupo de google knockoutjs pero realmente no me dio una respuesta satisfactoria.
Puedo ver una razón si quería inicializar el modelo con algunos datos, por ejemplo:
var viewModel = function(person) {
this.firstname= ko.observable(person.firstname);
};
var person = ... ;
ko.applyBindings(new viewModel(person));
Pero si no lo hago, ¿importa qué estilo elijo?
prototype
(métodos que a menudo, por ejemplo, obtienen datos del servidor y actualizan el modelo de vista en consecuencia). Sin embargo, obviamente podría declararlos como una propiedad de un objeto literal, por lo que realmente no puedo ver la diferencia.Respuestas:
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
this
igual a la instancia que se está creando. Esto significa que puedes hacer:Por lo tanto, su observable calculado puede estar vinculado al valor apropiado de
this
, incluso si se llama desde un ámbito diferente.Con un objeto literal, deberías hacer:
En ese caso, podrías usar
viewModel
directamente en el observable calculado, pero se evalúa de inmediato (por defecto), por lo que no puede definirlo dentro del objeto literal, comoviewModel
que no se define hasta después de que se cerró 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 usar para asegurarse de que
this
siempre sea apropiado es establecer una variable en la función igual al valor apropiadothis
y usarla en su lugar. Esto sería como:Ahora, si está dentro del alcance de un artículo individual y llama
$root.removeItem
, el valor dethis
será en realidad los datos vinculados a ese nivel (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 los navegadores modernos y agregado por KO, si no es compatible. En ese caso, se vería así:Hay mucho más que podría decirse sobre este tema y muchos patrones que podría explorar (como el patrón de módulo y el patrón de módulo revelador), pero básicamente el uso de una función le brinda más flexibilidad y control sobre cómo se crea el objeto y la capacidad de referenciar variables que son privadas para la instancia.
fuente
self
ythis
son iguales, por lo que cualquiera será equivalente. En la función removeItem,self
se vuelve más útil, yathis
que ya no sería la instancia actual cuando se ejecuta en el contexto de un elemento secundario.Yo uso un método diferente, aunque similar:
Un par de razones:
this
, lo que puede confundir cuando se usa dentro deko.computed
s etc.new viewModel()
)fuente
My viewModel is a singleton, I don't need to create multiple instances (i.e. new viewModel())
pero no está claro lo que está tratando de decir, ¿I don't need to create multiple instances
puede venir con más uso para que uno pueda entender la ventaja de su enfoque? graciasfunction
es porque lo ejecutarías más de una vez. Sin embargo, en mi ejemplo sobre, es una función anónima invocada de inmediato, por lo que no se creará más de una vez. Es muy similar al Object Literal en el ejemplo anterior, pero te da más aislamiento