Dans knockout js, je vois View Models déclaré comme étant:
var viewModel = {
firstname: ko.observable("Bob")
};
ko.applyBindings(viewModel );
ou:
var viewModel = function() {
this.firstname= ko.observable("Bob");
};
ko.applyBindings(new viewModel ());
Quelle est la différence entre les deux, le cas échéant?
J'ai trouvé cette discussion sur le groupe google knockoutjs mais cela ne m'a pas vraiment donné de réponse satisfaisante.
Je peux voir une raison si je voulais initialiser le modèle avec des données, par exemple:
var viewModel = function(person) {
this.firstname= ko.observable(person.firstname);
};
var person = ... ;
ko.applyBindings(new viewModel(person));
Mais si je ne le fais pas, le style que je choisis est-il important?
L'utilisation d'une fonction pour définir votre modèle de vue présente quelques avantages.
Le principal avantage est que vous avez un accès immédiat à une valeur de this
égale à l'instance en cours de création. Cela signifie que vous pouvez faire:
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);
};
Ainsi, votre observable calculé peut être lié à la valeur appropriée de this
, même si elle est appelée depuis une autre portée.
Avec un objet littéral, vous devriez faire:
var viewModel = {
first: ko.observable("Bob"),
last: ko.observable("Smith"),
};
viewModel.full = ko.computed(function() {
return this.first() + " " + this.last();
}, viewModel);
Dans ce cas, vous pouvez utiliser viewModel
directement dans l'observable calculé, mais celui-ci est évalué immédiatement (par défaut) et vous ne pouvez donc pas le définir dans l'objet littéral, car viewModel
n'est pas défini. jusqu'à ce que l'objet littéral soit fermé. Beaucoup de gens n'aiment pas que la création de votre modèle d'affichage ne soit pas encapsulée dans un seul appel.
Un autre modèle que vous pouvez utiliser pour vous assurer que this
est toujours approprié consiste à définir une variable dans la fonction égale à la valeur appropriée de this
et à l'utiliser à la place. Ce serait comme:
var ViewModel = function() {
var self = this;
this.items = ko.observableArray();
this.removeItem = function(item) {
self.items.remove(item);
}
};
Maintenant, si vous êtes dans la portée d'un élément individuel et appelez $root.removeItem
, la valeur de this
sera en réalité la donnée liée à ce niveau (qui serait l’élément). En utilisant self dans ce cas, vous pouvez vous assurer qu'il est supprimé du modèle de vue globale.
Une autre option consiste à utiliser bind
, qui est pris en charge par les navigateurs modernes et ajouté par KO, s'il n'est pas pris en charge. Dans ce cas, cela ressemblerait à:
var ViewModel = function() {
this.items = ko.observableArray();
this.removeItem = function(item) {
this.items.remove(item);
}.bind(this);
};
Il y a beaucoup plus à dire sur ce sujet et de nombreux modèles à explorer (tels que le modèle de module et le modèle de module révélant), mais l'utilisation d'une fonction vous donne plus de flexibilité et de contrôle sur la manière dont l'objet est créé et la possibilité de faire référence à les variables qui sont privées à l'instance.
J'utilise une méthode différente, bien que similaire:
var viewModel = (function () {
var obj = {};
obj.myVariable = ko.observable();
obj.myComputed = ko.computed(function () { return "hello" + obj.myVariable() });
ko.applyBindings(obj);
return obj;
})();
Couple de raisons:
this
, ce qui peut créer de la confusion lorsqu'il est utilisé dans ko.computed
S etc.new viewModel()
)