klee-contrib/focus4

[Form] Améliorer le `reset` automatique.

Closed this issue · 2 comments

JabX commented

Chaque nœud et sous-nœud de formulaire implémente sa propre méthode reset (qui est grosso-modo un formNode.replace(toFlatValues(storeNode))), et le reset automatique déclenché par une mise à jour du nœud source est une simple réaction sur le nœud racine.

Cela veut dire qu'il est impossible de charger partiellement des données dans un sous-nœud (toutes les données doivent toujours être chargées dans le nœud source pour rappel, jamais dans le nœud de formulaire) dans lancer un reset global du nœud.

Il faudrait que ça marche bien tout ça, avec chaque nœud qui gère sa propre réaction, sans toucher à ses sous-nœuds (qui seront donc couverts par leur propre réaction).

JabX commented

Aussi, il faudrait que le reset soit plus robuste au rechargement du nœud source à l'identique. Exemple:

const entity = makeFormNode(node);
node.replace(await load());
console.log(entity.prop.value); // OK
entity.clear();
console.log(entity.prop.value); // undefined, OK
node.replace(await load()); // Le store n'est finalement pas modifié, puisqu'on y remet la même chose.
console.log(entity.prop.value); // undefined, KO…
JabX commented

La solution trouvée est plutôt cool (et réalisée dans le commit sus-cité) :

  • (On enlève la réaction globale de reset sur le FormNode)
  • On ajoute un intercepteur (intercept) sur chaque champ source qui affecte toute valeur affectée au champ source au champ équivalent du formulaire. On utilise un intercepteur pour que la mise à jour du champ de formulaire soit toujours effectuée, même si la valeur du champ source est identique. En effet, avec un observeur ou une réaction on passerait à côté des "invariants" et on aurait le problème présenté dans le commentaire précédent.
  • On ajoute un observeur (observe) sur les noeuds listes sources pour réagir aux ajouts et suppressions d'éléments (push, replace, ...). L'observeur est toujours déclenché même si on réaffecte les mêmes objets, donc il vaut mieux utiliser observe qui est l'outil adapté et permet d'accéder aux éléments supprimés (ce qu'intercept ne peut pas faire).
  • Ces différents intercepteurs et observeurs peuvent être arrêtés via la méthode form.dispose() ajoutée sur les noeuds de formulaire (simples et listes), qui remplace le stopSync() de la racine du nœud qui gérait la réaction globale. dispose() sera appelé au démontage du formulaire (celui du <Form> lié à actions lié à entity) (stopSync() était appelé au même endroit s'il était présent). Il est nécessaire de nettoyer les réactions quand on arrête d'utiliser le formNode est c'est le seul endroit ou on peut le faire automatiquement.

Pour l'instant tous les tests existants passent avec ça, mais il en faudrait beaucoup plus parce qu'ils ne testent que des cas très simples.