14
votes

ChangeNotifierProvider vs ChangeNotifierProvider.value

Je suis assez nouveau dans ce cadre et je travaille sur la gestion de l'état à l'aide du package de fournisseur où je rencontre ChangeNotifierProvider et ChangeNotifierProvider.value , mais je suis incapable de distinguer leur cas d'utilisation.

J'avais utilisé ChangeNotifierProvider à la place de ChangeNotifierProvider.value , mais cela ne fonctionne pas comme prévu.


0 commentaires

4 Réponses :


5
votes

La documentation officielle aide-t-elle?

Utilisez - ChangeNotifierProvider.value au fournisseur un existant ChangeNotifier :

ChangeNotifierProvider(
  builder: (_) => variable,   
  child: ... 
)

NE réutilisez PAS un ChangeNotifier existant en utilisant le constructeur par défaut.

ChangeNotifierProvider.value(
  value: variable,
  child: ...
)

Consultez également ce problème Github de l'auteur à ce sujet.


0 commentaires

4
votes

ValueNotifier et ChangeNotifier sont étroitement liés.

En fait, ValueNotifier est une sous-classe de ChangeNotifier qui implémente ValueListenable.

Voici l'implémentation de ValueNotifier dans le SDK Flutter:

/// A [ChangeNotifier] that holds a single value.
///
/// When [value] is replaced with something that is not equal to the old
/// value as evaluated by the equality operator ==, this class notifies its
/// listeners.
class ValueNotifier<T> extends ChangeNotifier implements ValueListenable<T> {
  /// Creates a [ChangeNotifier] that wraps this value.
  ValueNotifier(this._value);

  /// The current value stored in this notifier.
  ///
  /// When the value is replaced with something that is not equal to the old
  /// value as evaluated by the equality operator ==, this class notifies its
  /// listeners.
  @override
  T get value => _value;
  T _value;
  set value(T newValue) {
    if (_value == newValue)
      return;
    _value = newValue;
    notifyListeners();
  }

  @override
  String toString() => '${describeIdentity(this)}($value)';
}

Alors, quand devrions-nous utiliser ValueNotifier vs ChangeNotifier?

Utilisez ValueNotifier si vous avez besoin de reconstruire des widgets lorsqu'une valeur simple change. Utilisez ChangeNotifier si vous voulez plus de contrôle sur le moment où notifyListeners () est appelé.


0 commentaires

1
votes

Est une différence importante entre ChangeNotifierProvider.value et avec la fonction de création. Lorsque vous utilisez Provider dans une seule liste ou un élément de grille, Flatter supprime les éléments lorsqu'ils quittent l'écran et les ajoute à nouveau lorsqu'ils sont rentrés à l'écran dans de telles situations, ce qui se passe réellement est que le widget lui-même est réutilisé par Flutter et uniquement les données qui y est attaché change. Donc Flatter recycle le même widget, il ne le détruit pas et ne le recrée pas. lorsque nous utilisons Provider avec la fonction create.

ChangeNotifierProvider.value(
  value: new MyChangeNotifier(),
  child: ...
)

- ici, le contenu change au fil du temps et notre fournisseur ne viendra pas nous chercher.

Dans une seule liste ou élément de grille, nous devons utiliser la valeur de point du fournisseur.

ChangeNotifierProvider(
  create: (_) => new MyChangeNotifier(),
  child: ...
)


0 commentaires

21
votes

Prenons cela par étapes.

Qu'est-ce que ChangeNotifier?

Une classe qui étend ChangeNotifier peut appeler notifyListeners() chaque fois que les données de cette classe ont été mises à jour et que vous souhaitez informer un auditeur de cette mise à jour. Cette opération est souvent effectuée dans un modèle de vue pour avertir l'interface utilisateur de reconstruire la mise en page en fonction des nouvelles données.

Voici un exemple:

class _MyWidgeState extends State<MyWidge> {

  MyChangeNotifier myChangeNotifier;

  @override
  void initState() {
    myChangeNotifier = MyChangeNotifier();
    myChangeNotifier.doSomeInitializationWork();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<MyChangeNotifier>.value(
      value: myChangeNotifier,                           // <-- important part
      child: ... 

J'ai écrit plus à ce sujet dans un guide pour débutant sur l'architecture d'une application Flutter .

Qu'est-ce que ChangeNotifierProvider?

ChangeNotifierProvider est l'un des nombreux types de fournisseurs du package Provider . Si vous avez déjà une classe ChangeNotifier (comme celle ci-dessus), vous pouvez utiliser ChangeNotifierProvider pour la fournir à l'endroit où vous en avez besoin dans la disposition de l'interface utilisateur.

create: (context) => MyChangeNotifier(),

Notez en particulier qu'une nouvelle instance de la classe MyChangeNotifier a été créée dans cette ligne:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<MyChangeNotifier>(        // define it
      create: (context) => MyChangeNotifier(),              // create it
      child: MaterialApp(
        ...

          child: Consumer<MyChangeNotifier>(                // get it
            builder: (context, myChangeNotifier, child) {
              ...
                  myChangeNotifier.increment();             // use it

Ceci est fait une fois lorsque le widget est construit pour la première fois, et non lors des reconstructions suivantes.

À quoi sert ChangeNotifierProvider.value alors?

Utilisez ChangeNotifierProvider.value si vous avez déjà créé une instance de la classe ChangeNotifier . Ce type de situation peut se produire si vous avez initialisé votre classe ChangeNotifier dans la méthode initState() de la classe State de votre StatefulWidget .

Dans ce cas, vous ne voudriez pas créer une toute nouvelle instance de votre ChangeNotifier car vous ChangeNotifier tout travail d'initialisation que vous aviez déjà effectué. L'utilisation du constructeur ChangeNotifierProvider.value vous permet de fournir votre valeur ChangeNotifier pré-créée.

class MyChangeNotifier extends ChangeNotifier {
  int _counter = 0;
  int get counter => _counter;

  void increment() {
    _counter++;
    notifyListeners();
  }
}

Notez en particulier qu'il n'y a pas ici de paramètre de create , mais un paramètre de value . C'est là que vous transmettez votre ChangeNotifier classe ChangeNotifier . Encore une fois, n'essayez pas de créer une nouvelle instance ici.


1 commentaires

Je souhaite que toutes les réponses sur stackoverflow soient aussi bien écrites que celle-ci.