Meteor: utiliser les Sessions et réactiver
Quand devez-vous utiliser Session
et ReactiveVar
? J'utilise Session
variable comme moyen de communication entre les composants. Regardons Stackoverflow par exemple.
j'ai étiqueté trois composants hypothétiques. Regardons les filters
composant. Si vous cliquez sur Tags
puis Main
les composants montreront ses questions basées sur vos étiquettes préférées. Pour ce faire, je vais le mettre Session.set("Main/showTags", true)
lors de la Tags
bouton est cliqué. Dans le Composant principal, je vais avoir une fonction d'assistance, comme ci-dessous:
Template.Main.helpers({
posts: function() {
var isTags = Session.get("Main/showTags");
var isQuestions = Session.get("Main/showQuestions");
...
if (isTags) {
return Posts.find().sort({tags: 1}) // or something along the lines
} else if (isQuestions) ...
}
});
cela a bien fonctionné dans la plupart des cas mais j'ai vu de nombreux endroits que je devrais m'abstenir d'utiliser Session
et utiliser ReactiveVar
. Mais si j'utilise ReactiveVar
partout, alors j'aurais besoin de la référence à toutes les instances de modèle. Je espérer qu'il fonctionne bien entre les parents et les enfants modèles (ex. à l'intérieur du composant principal, il pourrait y avoir VoteAnswerViewsButtonTemplate
) mais comment voulez-vous faire avec ReactiveVar
quand vous voulez des éléments indépendants pour se parler?
Voici ma dernière question. Comment puis-je utiliser de façon appropriée Session
et ReactiveVar
pour garder la portée des composants et les faire communiquer entre eux aussi? Aussi, si j'utilise Session
comme je le fais maintenant, est-ce que je pollue inutilement l'Espace-nom mondial?
connexes Documents:
3 réponses
autant Que je sache, il n'y a pas intégré les caractéristiques concernant Session
variables qui les différencient d'une variable globale de dictionnaire réactive régulière (comme @Kyll stated) que vous déclareriez, par exemple, dans votre client.js
fichier. La seule différence est l' Session
"limitation" de la nécessité d'être accessible à l'ensemble de l'application.
je suis très heureux de prendre avantage de cette différence, lorsque j'utilise un réactif dictionnaire ou variables réactives dans une plus petite portée. Je considère que j'ai trois périmètres:
1-portée mondiale. Par exemple: le langage courant de L'UI, la peau de L'UI. J'utilise Session
pour que. Des données simples et globales, pas celles qui pourraient être confondues avec quoi que ce soit d'autre.
2-un groupe de gabarits. disons, par exemple, que je crée une page pour générer et personnaliser les fichiers pdf dans mon application. Je ne vais pas réutiliser tous les composants ailleurs. Mon cluster est un dossier avec trois fichiers, appelons -pdfgenerator.html
,pdfgenerator.js
et pdfgenerator_controller.js
.
j'utilise pdfgenerator_controller.js
étendre la route avec tous les détails.
Dans le pdfgenerator.js
fichier, j'ai plusieurs gabarits que j'utilise tous dans le cluster. Au début du fichier, je crée un dictionnaire réactif pageSession
(similaire aux variables réactives) et je l'utilise dans tout mon cluster. Il me permet de transmettre des données parmi tous mes composant.
3 - portée locale. Si c'est un modèle unique ou d'un composant réutilisable, il est destiné à travailler seul. Je n'utiliserai pas de Session vars pour ceux-là non plus. Je ne veux pas surcharger la Session
nom de l'espace. Ce que je fais, c'est transmettre à mon modèle toutes les données dont j'ai besoin pour l'exploiter pendant son instanciation.
Il pourrait être d'Entretoises:
{{> mySingleTemplate data=myData}}
ou en utilisant Javascript:
Blaze.renderWithData(Template.mySingleTemplate , myData, self.firstNode);
dans le local champ d'application les cas, j'utilise aussi un reactive dictionary
ou reactive vars
juste pour gérer la réactivité qui se produit à l'intérieur du modèle unique. Dans ce cas, j'essaie d'éviter les situations où je dois la renvoyer les données vers le modèle parent. Si j'ai (c'est à dire je ne vais probablement pas faire un paquet), j'utilise un local minimongo collecte déclarée comme globale dans la portée du modèle parent. De cette façon, je peux transmettre des informations du composant réutilisable à son parent.
exemple: un modèle de téléchargement. J'utilise minimongo pour stocker le nom, la taille, le type, l'état et l'url de chaque fichier téléchargé. La collection minimongo est partagée entre le modèle de formulaire parent et le modèle de téléchargement d'enfant.
résultat: je n'utilise Session
variables pour l'information de base et globale. Si la structure de données que j'ai besoin de partager à l'échelle mondiale est trop complexe/trop vaste, Je m'appuie sur une collection.
je suis curieuse de savoir si je comprends bien, donc, c'est aussi beaucoup une réponse qu'un test pour voir si des gens sont d'accord avec ma façon de faire les choses. Tous les commentaires et conseils sont les bienvenus.
Session vars obtenir un mauvais rap. La vérité est, qu'ils vont bien jusqu'à ce que votre application soit grande. Vous saurez quand il est temps de vous éloigner de la Session vars quand:
- Vous ne pouvez pas garder le var, les noms des droites (eg wtf n'
isColumnHidden
encore?) Ou, les vars de session forment des clusters naturels (3 vars de session pour les tooltips, 5 pour les tags, etc.). - vous voulez que les informations de la Session dans l'url de sorte que vous pouvez envoyer à quelqu'un un un lien & ILS voir ce que vous voyez
alors, comment faire vous résoudre chaque problème?
pour le premier exemple, créez un paquet. Par exemple, dans un de mes plus grands projets je crée un
rightSideMenu
etleftSideMenu
paquet. Chacun a son propre Réactivedict que j'exporte à la portée globale (par exemplerightMenu.RD.get('col1Hidden')
). L'approche reste ainsi modulaire. Je peux réécrire complètement mon code de menu, mais tant que j'expose la réactivation, L'API reste la même. Qui a dit, j'utilise toujours un var de Session pour afficher / masquer la gauche et la droite des menus. Pourquoi? parce que Session est l'utilisation parfaite pour les menus. Je ne veux pas qu'un menu caché persiste à travers les sessions de navigateur (jamais fermer quelque chose que vous ne saviez pas comment rouvrir?), mais je ne veux persister à travers les routes. En d'autres termes, je veux qu'il dure pour que la navigation Session.si vous voulez que l'url contienne des informations de session, vous devez utiliser params ou query params. Par exemple, si vous avez une carte avec 100 marqueurs et que l'utilisateur veut l'envoyer page à son ami avec un marqueur spécifique sélectionné, il est logique que l'url soit quelque chose comme
url.com/marker20
. Mais pourquoi s'arrêter là? Vous pouvez également inclure le lat & lng du map center:url.com/marker/40.23432/122.2342
. C'est peut-être trop, peut-être pas. À vous de décider. Dans votre exemple, cela fait BEAUCOUP plus de sens que de stockerisTag
dans un var de session parce qu'il permet aux gens de le marquer, d'utiliser le bouton arrière, de le partager, et de le changer sans utiliser leur souris (Oui, votre base d'utilisateur est aussi paresseuse que je le suis).
une note supplémentaire sur votre configuration actuelle est que vous utilisez des flags pour quelque chose qui est mutuellement exclusif, conduisant à un enfer conditionnel. Si vous avez 2 vars qui ne peuvent pas être à la fois vrai, stop & rethink la conception. Donc, si je devais utiliser session vars, je ferais quelque chose comme:
currentTemplate = Session.get('filter')
{{Template.dynamic template=currentTemplate}}
à la fin, vous aurez besoin de penser à beaucoup plus que juste réactivables. Ce sujet de dépendances? Pas chaque module a besoin d'accéder à des dépendances de tous les autres module. Il en va de même pour les collections, les méthodes et même les CSS. Je dis laissez-le croître organiquement & quand il vous frappe "Hé, c'est un composant" puis le transformer en un paquet, exporter une variable, et le garder modulaire. D'ici là, les var sont très bien.
votre problème ne pollue pas la portée globale. Alors pourquoi ne pas faire votre propre?
myComponentScope = {}; //Declare a global scope for this component
alors placez juste autant de choses que vous voulez à l'intérieur. Par exemple,
myComponentScope.foo = new Reactive-Var('foo');
Et si vous voulez quelque chose qui ressemble à Session
vous pouvez ajouter Réactif-Dict:
meteor add reactive-dict
Et utiliser de cette façon:
myComponentScope = new Reactive-Dict(/* Optional name */);
le nom optionnel rend le dictionnaire persistant à travers les pousses de code à chaud.
L'API pour ce dictionnaire est même en tant que Session
.
Ainsi, lorsque vous avez quelque chose de strictement local (un modèle), aller faire un Reactive-Var
.
Quand il s'agit de quelque chose de plusieurs modèles de la même sorte partager, aller pour votre propre portée.
Si c'est quelque chose de si important, toute votre application en aura besoin, utilisez Session
.