Cet article a été évalué par des pairs par Michel Weststrate et Aaron Boyer. Merci à tous les pairs examinateurs de SitePoint pour avoir rendu le contenu de SitePoint parfait!
Si vous avez déjà écrit une application plus complexe que très simple en utilisant jQuery, vous avez peut-être eu le problème de garder différentes parties de l'interface utilisateur en synchronisation. Souvent, les modifications apportées aux données doivent être reflétées dans plusieurs endroits, et à mesure que l'application se développe, vous pouvez vous retrouver en difficulté. Pour contrôler cette confusion, les événements sont souvent utilisés pour permettre à différentes parties de l'application de savoir quand des modifications se sont produites.
Alors, comment avez-vous géré l'état de l'application aujourd'hui? Je vais prendre la liberté de dire que vous sursoussez les changements. C'est exact. Je ne te connais même pas, mais je vais le souligner. Si vous n'êtes pas sursouscripteur, je suis sûr que vous avez travaillé trop dur.
Bien sûr, à moins que vous n'utilisiez MOBX…
Points clés
autorun
implémente la fonction Qu'est-ce que "État"?
fullName()
C'est un personnage. Hé, c'est moi! J'ai un prénom, un nom et un âge. De plus, si j'ai des problèmes, la fonction
var person = { firstName: 'Matt', lastName: 'Ruby', age: 37, fullName: function () { return this.firstName + ' ' + this.lastName; } };
Comment allez-vous informer vos différentes sorties (vues, serveurs, journaux de débogage) de modifications à cette personne? Quand allez-vous déclencher ces notifications? Avant Mobx, j'utiliserais un setter qui déclenche un événement jQuery personnalisé ou des signaux JS. Ces options me servent bien, mais mon utilisation est loin d'être méticuleuse. Si une partie de l'objet Person change, je déclencherai un événement "modifié".
Supposons que j'ai un code de vue qui montre mon nom. Si je change mon âge, la vue sera mise à jour car elle est liée à l'événement modifié de cette personne. <🎜>
var person = { firstName: 'Matt', lastName: 'Ruby', age: 37, fullName: function () { return this.firstName + ' ' + this.lastName; } };
Comment resserrer ce sur-effacer? Simple. Définissez simplement un secteur pour chaque champ et définissez un événement séparé pour chaque modification. Attendez - si vous voulez changer l'âge et le nom de premier à la fois, vous pouvez commencer à surdiquer. Vous devez créer un moyen de retarder le déclenchement des événements jusqu'à ce que les deux modifications soient terminées. Cela ressemble à du travail, et je suis paresseux ...
MOBX vient le sauvetage
MOBX est une bibliothèque de gestion de l'État simple, ciblée, efficace et discrète développée par Michel Weststrate.
de la documentation MOBX:
Faites simplement quelque chose à propos de l'état et MOBX s'assurera que votre application respecte ces modifications.
person.events = {}; person.setData = function (data) { $.extend(person, data); $(person.events).trigger('changed'); }; $(person.events).on('changed', function () { console.log('first name: ' + person.firstName); }); person.setData({age: 38});
avez-vous remarqué la différence? mobx.observable
est le seul changement que j'ai apporté. Voyons à nouveau l'exemple console.log
:
var person = mobx.observable({ firstName: 'Matt', lastName: 'Ruby', age: 37, fullName: function () { return this.firstName + ' ' + this.lastName; } });
En utilisant autorun
, MOBX observera uniquement le contenu accessible.
Si vous pensez que c'est bien, consultez ce qui suit:
mobx.autorun(function () { console.log('first name: ' + person.firstName); }); person.age = 38; // 打印为空 person.lastName = 'RUBY!'; // 仍然为空 person.firstName = 'Matthew!'; // 此处触发
intéressé? Je sais que tu es intéressé.
Mobx Core Concept
mobx.autorun(function () { console.log('Full name: ' + person.fullName); }); person.age = 38; // 打印为空 person.lastName = 'RUBY!'; // 触发 person.firstName = 'Matthew!'; // 也触发
Les objets observables MOBX ne sont que des objets. Dans cet exemple, je n'observe rien. Cet exemple montre comment commencer à intégrer MOBX dans votre base de code existante. Utilisez simplement mobx.observable()
ou mobx.extendObservable()
pour commencer.
var log = function(data) { $('#output').append('' +data+ ''); } var person = mobx.observable({ firstName: 'Matt', lastName: 'Ruby', age: 34 }); log(person.firstName); person.firstName = 'Mike'; log(person.firstName); person.firstName = 'Lissy'; log(person.firstName);
Que voulez-vous faire lorsque vos observables changent, non? Permettez-moi de présenter autorun()
, qui déclenchera un rappel lorsqu'une valeur observable référencée changera. Notez que dans l'exemple ci-dessus, autorun()
ne tirera pas lorsque l'âge changera.
var person = mobx.observable({ firstName: 'Matt', lastName: 'Ruby', age: 0 }); mobx.autorun(function () { log(person.firstName + ' ' + person.age); }); // 这将打印Matt NN 10次 _.times(10, function () { person.age = _.random(40); }); // 这将什么也不打印 _.times(10, function () { person.lastName = _.random(40); });
avez-vous vu cette fonction fullName
? Notez qu'il n'a pas de paramètres et get
? MOBX créera automatiquement une valeur calculée pour vous. C'est l'une de mes fonctionnalités MOBX préférées. Notez qu'il y a quelque chose d'étrange dans person.fullName
? Regardez à nouveau. C'est une fonction, vous pouvez voir le résultat sans l'appeler! Habituellement, vous appellerez person.fullName()
au lieu de person.fullName
. Vous venez de rencontrer votre premier JS Getter.
Le plaisir ne se termine pas ici! MOBX surveillera les dépendances des valeurs calculées pour les modifications et s'exécute uniquement lorsqu'elles changent. Si rien ne change, la valeur en cache sera renvoyée. Veuillez consulter la situation suivante:
var person = mobx.observable({ firstName: 'Matt', lastName: 'Ruby', age: 0, get fullName () { return this.firstName + ' ' + this.lastName; } }); log(person.fullName); person.firstName = 'Mike'; log(person.fullName); person.firstName = 'Lissy'; log(person.fullName);
plusieurs fois, mais la seule fois que la fonction s'exécute, c'est quand FirstName ou LastName change. C'est l'une des façons dont Mobx peut considérablement accélérer les applications. person.fullName
(Le contenu suivant omet certains exemples de code et explications détaillées, et conserve le contenu et la structure de base)
Mettez Mobx en usageconstruisons quelque chose avant que ce soit trop ennuyeux.
Il s'agit d'un exemple simple non mobx qui montrera le nom complet de la personne chaque fois qu'il change.
Notez que même si nous n'avons jamais changé le nom, le nom a été rendu 10 fois. Vous pouvez optimiser ce problème à l'aide de nombreux événements ou vérifier une sorte de modification de la charge utile. C'est trop de travail.
C'est le même exemple construit avec Mobx:
Notez qu'il n'y a pas d'événements, de déclencheurs ou de. Avec MOBX, vous avez affaire à la dernière valeur et au fait qu'elle a changé. Notez qu'il n'a été rendu qu'une seule fois? C'est parce que je n'ai rien changé que autorun
soit surveillé.
construisons quelque chose de légèrement moins trivial:
Ici, nous sommes en mesure de modifier l'objet entier de la personne et de surveiller automatiquement la sortie des données. Maintenant, il y a des points doux dans cet exemple, et la chose la plus notable est que la valeur d'entrée est hors de synchronisation avec l'objet personne. Résolvons ce problème:
Je sais, vous avez une autre plainte: "Ruby, tu as trop rendu!" C'est pourquoi beaucoup de gens choisissent d'utiliser React. React vous permet de casser facilement la sortie en widgets qui peuvent être rendus séparément.
Pour l'exhaustivité, voici un exemple jQuery que j'ai optimisé.
Vais-je faire quelque chose comme ça dans une vraie application? Probablement pas. Si j'ai besoin de cette granularité, j'utiliserai React à tout moment. Lorsque j'utilise MOBX et jQuery dans une vraie application, j'utilise un suffisamment nuancé autorun()
que je ne reconstruis pas l'ensemble du DOM à chaque fois que je le change.
Vous êtes arrivé à ce point, alors voici le même exemple construit avec React et Mobx
construisons un diaporama
Comment représenterez-vous le statut du diaporama? Commençons par une seule usine de diapositives:
Nous devrions avoir quelque chose à agréger toutes nos diapositives. Construisons-le maintenant:
Le diaporama a commencé! Ceci est plus intéressant car nous avons un tableau observable de diapositives qui nous permet d'ajouter et de supprimer les diapositives de la collection et de mettre à jour notre interface utilisateur en conséquence. Ensuite, nous ajoutons la valeur calculée activeSlide
, qui se tiendra à jour au besoin.
Rendons notre diaporama. Nous ne sommes pas prêts pour la sortie HTML, nous allons donc imprimer uniquement vers la console.
C'est cool, nous avons quelques diapositives, autorun
juste imprimer leur statut actuel. Changeons une ou deux diapositives:
Il semble que notre autorun
fonctionne. Si vous modifiez quelque chose que autorun
est surveillé, il tirera. Changeons la dérivation de sortie de la console en html:
Nous avons maintenant eu l'affichage de base de ce diaporama, mais il n'y a pas encore d'interaction. Vous ne pouvez pas cliquer sur la vignette et modifier l'image principale. Cependant, vous pouvez facilement modifier le texte de l'image et ajouter un diaporama à l'aide de la console:
Créons notre première et seule action pour configurer le diaporama sélectionné. Nous devrons modifier slideShowModelFactory
en ajoutant:
Vous pouvez demander, pourquoi avez-vous besoin d'utiliser une opération? Une bonne question! Les opérations MOBX ne sont pas nécessaires, comme je l'ai montré dans d'autres exemples de changements de valeurs observables.
L'opération vous sera utile à plusieurs aspects. Tout d'abord, toutes les opérations MOBX s'exécutent dans une transaction. Cela signifie que notre autorun
et d'autres réactions MOBX attendront que l'opération se termine avant le déclenchement. Pensez-y. Que se passe-t-il si j'essaie de désactiver la diapositive active en dehors de la transaction et d'activer la diapositive suivante? Notre autorun
sera déclenché deux fois. La première course sera gênante, car il n'y aura pas de diapositives actives disponibles pour l'affichage.
En plus de leur nature transactionnelle, les opérations MOBX ont tendance à faciliter le débogage. Le premier paramètre facultatif auquel j'ai transmis mobx.action
est la chaîne "Set Active Slide". Cette chaîne peut être sortie à l'aide de l'API de débogage de MOBX.
Donc, nous avons notre opération, utilisons jQuery pour la connecter à:
c'est tout. Vous pouvez maintenant cliquer sur la vignette et l'activité se propagera comme prévu. Voici un exemple de diaporama:
Il s'agit d'un exemple du même diaporama à l'aide de React.
Remarque, je n'ai pas du tout changé le modèle? En termes de MOBX, React n'est qu'un autre dérivé de vos données, tels que jQuery ou Console.
AVERTISSEMENTS POUR JQUERY Slide Show Exemple
Veuillez noter que je n'ai pas optimisé l'exemple jQuery. Nous détruisons l'intégralité du diaporama DOM à chaque fois que nous le changeons. En cassant, je veux dire que nous remplaçons tous les HTML pour le diaporama à chaque clic. Si vous construisez un puissant diaporama basé sur JQuery, vous pouvez ajuster le DOM après le rendu initial en définissant et en supprimant la classe active et en modifiant les attributs de mainImage
. src
Si vous souhaitez en savoir plus sur MOBX, consultez d'autres ressources utiles ci-dessous:
Si vous avez des questions, veuillez me le faire savoir dans les commentaires ci-dessous, ou trouvez-moi dans la chaîne Mobx Gitter.
FAQ sur la gestion de l'état de l'application JavaScript avec mobx
(La partie FAQ est omise du contenu suivant, car l'article est trop long et n'a pas grand-chose à voir avec le contenu de base.)
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!