Dans knockout js, je vois View Models déclaré comme:
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 quelques 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, quel style choisir?
prototype
(des méthodes qui, souvent, par exemple, récupèrent les données du serveur et mettent à jour le modèle de vue en conséquence). Cependant, vous pouvez toujours les déclarer comme une propriété d'un objet littéral, donc je ne vois pas vraiment de différence.Réponses:
Il y a quelques avantages à utiliser une fonction pour définir votre modèle de vue.
Le principal avantage est que vous avez un accès immédiat à une valeur
this
égale à l'instance en cours de création. Cela signifie que vous pouvez faire:Ainsi, votre observable calculé peut être lié à la valeur appropriée de
this
, même s'il est appelé à partir d'une portée différente.Avec un objet littéral, il faudrait faire:
Dans ce cas, vous pouvez utiliser
viewModel
directement dans l'observable calculé, mais il est évalué immédiatement (par défaut), vous ne pouvez donc pas le définir dans le littéral de l'objet, commeviewModel
n'est défini qu'après la fermeture du littéral objet. Beaucoup de gens n'aiment pas que la création de votre modèle de vue ne soit pas encapsulée dans un seul appel.Un autre modèle que vous pouvez utiliser pour vous assurer qu'il
this
est toujours approprié consiste à définir une variable dans la fonction égale à la valeur appropriée dethis
et à l'utiliser à la place. Ce serait comme:Maintenant, si vous êtes dans la portée d'un élément individuel et appelez
$root.removeItem
, la valeur dethis
sera en fait les données liées à 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 utilise
bind
, qui est prise en charge par les navigateurs modernes et ajoutée par KO, si elle n'est pas prise en charge. Dans ce cas, cela ressemblerait à:Il y a beaucoup plus à dire sur ce sujet et de nombreux modèles que vous pouvez explorer (comme le modèle de module et le modèle de module révélateur), mais en gros, l'utilisation d'une fonction vous donne plus de flexibilité et de contrôle sur la façon dont l'objet est créé et la capacité de référence variables privées de l'instance.
la source
self
etthis
sont les mêmes, donc l'un ou l'autre sera équivalent. Dans la fonction removeItem,self
devient plus utile, commethis
ne serait plus l'instance actuelle lorsqu'elle est exécutée dans le contexte d'un élément enfant.J'utilise une méthode différente, mais similaire:
Quelques raisons:
this
, ce qui peut prêter à confusion lorsqu'il est utilisé dansko.computed
s, etc.new viewModel()
)la source
My viewModel is a singleton, I don't need to create multiple instances (i.e. new viewModel())
mais ce que vous essayez de dire n'est pas clair, vousI don't need to create multiple instances
pouvez utiliser plus d'utilisation pour que vous puissiez comprendre les avantages de votre approche. mercifunction
est parce que vous l'exécuteriez plus d'une fois. Cependant, dans mon exemple, c'est une fonction anonyme immédiatement invoquée, donc elle ne sera pas créée plus d'une fois. Il est très similaire au Object Literal dans l'exemple ci-dessus, mais vous donne plus d'isolement