recorrer propiedades objetos objeto literales imprimir eliminar elemento dinamico diccionario crear array javascript knockout.js

javascript - propiedades - Diferencia entre los modelos de vista eliminatoria declarados como objetos literales vs funciones



propiedades javascript (2)

En nocauts js veo modelos de vista 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 los hay?

Encontré esta discusión en el grupo de Google knockoutjs, pero no me dio una respuesta satisfactoria.

Puedo ver una razón si quisiera 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?


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 puedes 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); };

Por lo tanto, su observable computarizado puede vincularse al valor apropiado de this , incluso si se llama desde un alcance diferente.

Con un objeto literal, tendrías 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, podría usar viewModel directamente en el observable calculado, pero se evalúa de forma inmediata (de manera predeterminada), por lo que no podría definirlo dentro del literal del objeto, ya que viewModel no se define hasta después del cierre del 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 apropiado de this y usarla 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 está en el alcance de un elemento individual y llama a $root.removeItem , el valor de this será realmente los datos que se vincularán a ese nivel (que sería el elemento). Al utilizar 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í:

var ViewModel = function() { this.items = ko.observableArray(); this.removeItem = function(item) { this.items.remove(item); }.bind(this); };

Se podría decir mucho más 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 usar una función le da más flexibilidad y control sobre cómo se crea el objeto y la capacidad de referencia. Variables que son privadas a la instancia.


Yo uso un método diferente, aunque similar:

var viewModel = (function () { var obj = {}; obj.myVariable = ko.observable(); obj.myComputed = ko.computed(function () { return "hello" + obj.myVariable() }); ko.applyBindings(obj); return obj; })();

Par de razones:

  1. No usar this , lo que puede ko.computed confusión cuando se usa dentro de ko.computed s, etc.
  2. My viewModel es un singleton, no necesito crear múltiples instancias (es decir, new viewModel() )