2015-03-10 2 views
0

J'ai un formulaire réactif sur lequel je travaille et je dois résoudre un problème. Le problème est que mes utilisateurs utilisent des tablettes/téléphones portables sur des connexions cellulaires plus lentes, et parfois une connexion lâche. Lorsque la connexion est rétablie, Meteor déclenche tous les messages DDP, déclenchant ainsi la réactivité dans le formulaire, écrasant ainsi toute entrée de formulaire que l'utilisateur a effectuée mais pas enregistrée. J'ai donc eu l'idée d'avoir des valeurs temporaires enregistrées dans les documents, de sorte que l'utilisateur change les entrées de formulaire, les changements sont stockés dans une valeur "temp" jusqu'à ce qu'ils frappent Enregistrer, à quel moment je copie simplement la valeur de temp sur la valeur réelle et l'effacer. Lors de l'affichage, je vérifie simplement s'il y a une valeur de température, et si c'est le cas, affichez-la et, si ce n'est pas le cas, affichez la valeur enregistrée originale.Désactivation de la réactivité lors de la modification du champ

Cela fonctionne très bien pour les champs non textuels comme les cases d'option et les cases à cocher, mais cela ne fonctionne pas du tout pour les entrées de texte.

Le problème semble être lié à la réactivité. Comme les types d'utilisateurs, j'ai un même gestionnaire situé sur change et keydown (j'ai aussi essayé keypress et keyup) qui se déclenche tout simplement déclencher une mise à jour des valeurs temporaires comme celle-ci:

'change .responseInput, keydown .responseInput': function(event, tmpl) { 
    var response = Blaze.getData(tmpl.$('.headerDiv')[0]); 
    var val = response.lastResponseValue; 
    if (!val) { 
    val = new ResponseValue({ 
     response_id: response.id 
    }); 
    } 
    val.tempValues = getSelectedValues(tmpl.$('div.responseDiv')); 
    val.save(); 
} 

Dans ce gestionnaire d'événements, response.lastResponseValue simplement retourne la dernière valeur de réponse (je maintiens l'historique sur les valeurs entrées par l'utilisateur) et getSelectedValues() prend un élément DOM représentant la DIV autour du contrôle de formulaire et racle les valeurs sélectionnées, qui peuvent être une seule chaîne pour une zone de texte/textarea, ou tableau de valeurs de chaîne pour les cases à cocher. Ces pièces fonctionnent comme prévu. Ce qui ne fonctionne pas est le val.save(). Lorsque vous sélectionnez un champ de saisie de texte et que vous tapez rapidement, l'expérience montre que le texte tapé est ignoré/ignoré de façon aléatoire, probablement en raison de la réactivité. J'ai essayé d'encapsuler le gestionnaire d'événement dans un Tracker.nonreactive() pour désactiver la réactivité, mais cela ne semble pas aider. Je devine parce que ce n'est pas le save() qui est réactif, mais plutôt le find(). J'ai pensé à séparer le contenu de la valeur temp dans un document séparé. Alors la valeur réelle ne serait pas touchée, seulement la température attachée à elle, mais je finirais par devoir écrire le code qui a encore renvoyé la valeur de temp, sinon le problème original ne serait pas fixé du tout, auquel cas je pense que je serais de retour dans le même bateau où il y a une condition de course entre l'utilisateur et la réactivité.

Existe-t-il un moyen de désactiver temporairement la réactivité sur un document dans Meteor/Blaze? Ou y a-t-il simplement une meilleure méthode/modèle que je pourrais suivre qui améliorerait ce travail?

Répondre

0

Vos éléments de formulaire ne doivent pas être connectés à des valeurs réactives, sinon ils seront effacés comme vous le voyez, et également lors d'un push de code chaud. Au lieu de cela, vous devez initialiser le formulaire une seule fois lors du rendu du modèle. Si les valeurs sous-jacentes changent alors que l'utilisateur modifie le formulaire, le formulaire ne sera pas mis à jour automatiquement, ce qui est logique dans la plupart des cas d'utilisation.

Vous aurez toujours besoin de mettre à jour un stockage local lorsque l'utilisateur apporte des modifications, de sorte que vous pouvez remettre le formulaire à édité état si une poussée de code à chaud se produit.

Jetez un oeil à cela, il gère tout cela avec facilité:

http://viewmodel.meteor.com/

Tim

+0

Donc, j'ai lu sur le ViewModel. Je pense que c'est exactement ce dont j'ai besoin. Le seul problème que j'ai en échangeant, c'est que je n'ai pas trouvé un moyen de gérer la liaison lorsque la valeur peut être un tableau d'éléments, comme lorsque vous avez un tas de cases à cocher. Leur exemple de liaison par case à cocher suppose une VM pour chaque case à cocher. – CodeChimp

+0

J'ai raté le cas de la liaison de plusieurs cases à cocher à un tableau. Je vais mettre à jour ViewModel. C'est une solution facile. – Manuel

+0

Mettre à jour vers la version 1.3.2 et voir http://viewmodel.meteor.com/#checkedMultipleBk – Manuel