Flutter: Comment utiliser correctement les Hérité d'un Widget?
Quelle est la bonne façon d'utiliser un InheritedWidget? Jusqu'à présent j'ai compris qu'il vous donne la chance de propager les données vers le bas le Widget de l'arbre. Dans l'extrême si vous la mettre en RootWidget il sera accessible à partir de tous les Widgets dans l'arbre sur toutes les Routes, ce qui est bien parce que de toute façon je dois faire mon ViewModel/Modèle accessible pour mes trucs sans avoir à recourir à des variables globales ou des Singletons.
MAIS InheritedWidget est immuable, alors comment puis-je mettre à jour? Et plus important, comment sont mes Stateful Widgets déclenchée à reconstruire leurs sous-arbres?
Malheureusement, la documentation est ici très floue et après en avoir discuté avec beaucoup de personne ne semble vraiment savoir quelle est la bonne façon de l'utiliser.
J'ajoute une citation de Brian Egan:
Oui, je le vois comme un moyen de propager les données en bas de l'arbre. Ce que je trouve
déroutant, à partir de l'API docs:"Hérité des widgets référencées dans cette voie, sera la cause de la
la consommation de reconstruire lorsque les hérité widget lui-même change d'état."Quand j'ai lu cela, j'ai pensé:
Je pourrais trucs certaines données dans le InheritedWidget et de les transformer plus tard.
Lorsque que la mutation se produit, il faudra recompiler tous les Widgets
référence de mon InheritedWidget Ce que j'ai trouvé:Pour la mutation de l'État d'un InheritedWidget, vous avez besoin d'envelopper
dans un StatefulWidget Vous alors effectivement la mutation de l'état de l'
StatefulWidget et de transmettre ces données vers le InheritedWidget, qui
les mains des données à tous ses enfants. Toutefois, dans ce cas, il
semble de reconstruire l'ensemble de l'arborescence en dessous de la StatefulWidget, pas
juste les Widgets qui font référence à la InheritedWidget. Est-ce exact?
Ou cela est-il en quelque sorte de savoir comment faire pour ignorer les Widgets qui font référence à la
InheritedWidget si updateShouldNotify renvoie false?
OriginalL'auteur Thomas | 2018-03-26
Vous devez vous connecter pour publier un commentaire.
Le problème vient de votre devis, ce qui est incorrect.
Comme vous l'avez dit, InheritedWidgets sont, comme les autres widgets, immuable. Par conséquent, ils ne sont pas mise à jour. Ils sont créés de nouveau.
La chose est : InheritedWidget est juste un widget simple qui ne fait rien mais la détention de données. Ce n'est pas une logique de mise à jour ou que ce soit.
Mais, comme n'importe quel autre widget, il est associé à un
Element
.Et devinez quoi ? Cette chose est mutable et flutter va réutiliser dans la mesure du possible !
Le corrigé citation serait :
Il y a un grand discours sur la façon widgets/elements/renderbox sont branché ensemble.
Mais en bref, ils sont (de gauche est typique de votre widget, le milieu est "d'éléments", et la droite sont des "render cases") :
Le truc, c'est : Lorsque vous instanciez un nouveau widget ; flutter va le comparer à l'ancien. Réutiliser c'est "l'Élément", qui pointe vers une RenderBox. Et muter la renderbox propriétés.
Okey, mais comment est-ce répondre à ma question ?
Bien, c'est facile. Lors de l'instanciation d'un InheritedWidget, et puis l'appel de
context.inheritedWidgetOfExactType
(ouMyClass.of
qui est fondamentalement la même chose) ; ce qui est implicite, c'est qu'il sera à l'écoute desElement
associé à votreInheritedWidget
. Et à chaque fois queElement
obtient un nouveau widget, il va forcer l'actualisation de tous les widgets qui a appelé la méthode précédente.En bref, si vous remplacez un existant
InheritedWidget
avec une nouvelle marque ; flutter va voir qu'il a changé. Et le notifier à la limite des widgets d'une éventuelle modification.Si vous avez tout compris, vous devriez déjà avoir deviné la solution :
Envelopper votre
InheritedWidget
à l'intérieur d'unStatefulWidget
qui permettra de créer une nouvelle marqueInheritedWidget
chaque fois que quelque chose a changé !Dans cette situation, il est recommandé pour votre
InheritedWidget
de données pour en fait juste l'exemple de votreStatefulWidget
et ensuite faireInheritedWidget
privé. Pour vous éviter de copier coller et de possibles erreurs.Le résultat final réel de code serait :
Mais ne serait pas la création d'une nouvelle InheritedWidget reconstruire l'ensemble de l'arbre ?
Pas de ne pas necesseraly. En tant que votre nouveau InheritedWidget peut avoir exactement le même enfant comme avant. Et par exact, je veux dire même instance.
Les Widgets qui ont la même instance qu'ils avaient avant de ne pas reconstruire.
Et dans la plupart des situation (le fait d'Avoir un inheritedWidget à la racine de votre application), l'héritage widget est constante. Donc pas inutile de les reconstruire.
Pour votre premier commentaire, j'ai ajouté une troisième partie de ma réponse. Pour ce qui est fastidieux : je suis en désaccord. Un extrait de code peut générer assez facilement. Et de l'accès aux données est aussi simple que d'appeler
MyInherited.of(context)
.Vous ne savez pas si vous êtes intéressé, mais j'ai reçu l'Échantillon mis à jour avec cette technique: github.com/brianegan/flutter_architecture_samples/tree/master/... Un peu moins de dédoublement maintenant, c'est sûr! Si vous avez d'autres suggestions pour la mise en œuvre, serait l'amour d'une revue de code, si jamais vous avez quelques moments de rechange 🙂 Encore à essayer de comprendre la meilleure façon de partager cette logique de la croix-plate-forme (Flutter et Web) et de s'assurer qu'il est testable (en particulier la async genre de trucs).
Depuis le
updateShouldNotify
test est toujours en se référant à la mêmeMyInheritedState
exemple, n'est-ce pas toujours le retourfalse
? Certainement lebuild
méthode deMyInheritedState
est la création de nouveaux_MyInherited
cas, mais ladata
toujours des référencesthis
pas? Je vais avoir des problèmes... Fonctionne si je viens de coder en durtrue
.Ouais mon mauvais. Ne me souviens pas pourquoi je l'ai fait comme il est évident qu'elle ne fonctionne pas. Fixé par l'édition de vrai, merci.
OriginalL'auteur Rémi Rousselet
TL;DR
Ne pas utiliser de lourds calcul à l'intérieur de updateShouldNotify méthode et l'utilisation const au lieu de nouveau lors de la création d'un widget
Tout d'abord, nous devons comprendre ce qu'est un Widget, Élément et de Rendre des objets.
Maintenant, nous sommes prêts à plonger dans InheritedWidget et BuildContext la méthode de inheritFromWidgetOfExactType.
Un exemple, je recommande que nous considérons cet exemple de Flottement de la documentation sur InheritedWidget:
InheritedWidget - juste un widget qui met en oeuvre, dans notre cas, une méthode importante - updateShouldNotify.
updateShouldNotify - une fonction qui accepte un paramètre oldWidget et renvoie une valeur booléenne: true ou false.
Comme n'importe quel widget, InheritedWidget correspond à un Élément de l'objet. Il est InheritedElement. InheritedElement appel updateShouldNotify sur le widget à chaque fois que nous à en construire un nouveau widget(appel setState sur un ancêtre). Lorsque updateShouldNotify retourne vrai InheritedElement parcourt dépendances(?) et d'appeler la méthode didChangeDependencies.
Où InheritedElement obtient dépendances? Ici, nous devrions regarder inheritFromWidgetOfExactType méthode.
inheritFromWidgetOfExactType - Cette méthode définie dans BuildContext et
chaque Élément met en œuvre BuildContext interface (Élément == BuildContext). Ainsi, chaque Élément a de cette méthode.
Permet de regarder le code de inheritFromWidgetOfExactType:
Ici, nous essayons de trouver un ancêtre dans _inheritedWidgets cartographiés par type.
Si l'ancêtre est trouvé, on l'appellera alors inheritFromElement.
Le code pour inheritFromElement:
Alors maintenant, nous savons où InheritedElement obtient ses dépendances.
Regardons maintenant didChangeDependencies méthode.
Chaque Élément a de cette méthode:
Comme nous pouvons le voir, cette méthode constitue un élément sale et cet élément doit être reconstruit sur l'image suivante. Reconstruire signifie l'appel de la méthode construire sur le widget correspondant de l'élément.
Mais quid de l'Ensemble de la sous-arbre reconstruit quand j'ai reconstruire InheritedWidget?".
Ici, nous devons nous rappeler que les Widgets sont immuables et si vous créer un nouveau widget Flutter va reconstruire le sous-arbre. Comment pouvons-nous résoudre ce problème?
OriginalL'auteur maksimr
De la docs:
Que l'OP a noté, une
InheritedWidget
instance ne change pas... mais il peut être remplacé par une nouvelle instance au même endroit dans le widget de l'arbre. Lorsque cela arrive, il est possible que le régime enregistré d'widgets besoin d'être reconstruit. LeInheritedWidget.updateShouldNotify
méthode rend cette détermination. (Voir: docs)Alors, comment pourrait-il être remplacé? Un
InheritedWidget
instance peut être contenue par unStatefulWidget
, qui peut remplacer une ancienne version avec une nouvelle instance.OriginalL'auteur kkurian