flutter: ChangeNotifierProxyProvider no se inició en la compilación

CorePress2024-01-24  10

Estoy tratando de comprender los múltiples proveedores en Flutter. En mi aplicación, un proveedor debe cambiar según un valor de otro proveedor.

AuthProvider se inicia más arriba en el árbol de widgets durante la compilación. Funciona de maravilla con inicio de sesión automático si es posible...

En un widget ubicado en la parte inferior, intento iniciar otros dos proveedores. Uno, WhatEver, no depende de otros datos y se inicia en la compilación como se supone que debe hacerlo usando ChangeNotifierProvider.

Sin embargo, ProductList depende de AuthProvider. Si se cambia el estado de inicio de sesión, ProductList debería actualizarse en consecuencia.

En mis intentos, descubrí, es decir, encontré en SO, que ChangeNotifierProxyProvider es el camino correcto a seguir. Pero cuando ejecuto la aplicación, parece la parte "crear" de ChangeNotifierProxyP.rovider no se inicia cuando se construye el widget. Parece que el proveedor ProductList no se inicia hasta que se lee o se escribe en él.

¿Qué he entendido mal al usar MultiProviders y ChangeNotifierProxyProvider?

return MultiProvider(
        providers: [              
          ChangeNotifierProvider<WhatEver>(create: (context) => WhatEver()),
          ChangeNotifierProxyProvider<AuthProvider, ProductList>(
            create: (_) => ProductList(Provider.of<AuthProvider>(context, listen: false)),
            update: (_, auth, productList) => productList..reloadList(auth)
          ),
        ],

La lista de productos tiene este aspecto:

final AuthProvider _authProvider;

static const String _TAG = "Shop - product_list.dart : ";

ProductList(this._authProvider) {
    print(_TAG + "ProductList Provider initiated");
    reloadList(this._authProvider);
}

void reloadList(AuthProvider authProvider) {
    print(_TAG + "ProductList reload started");
    if (authProvider.user==null) {
        print(_TAG + "ProductList: _authProvider == null");
        _loadBuiltInList();
    } else {
        print(_TAG + "ProductList: user = " + authProvider.user.displayName);
        _loadFirestoreList();
    }
}

1

¿Podría ser perezoso? Ver esta respuesta

- Eduardo

27/03/2021 a las 13:34

La señora parece tener razón. Aunque abierto a otros problemas 😀

- usuario1086500

27/03/2021 a las 16:58



------------------------------------

Podría deberse a que no estás usando el contexto pasado en la llamada de creación cuando resuelves AuthProvider. Estás capturando el contexto dentro del alcance de toda esta declaración y luego resolviendo el AuthProvider a partir de eso.

Intente utilizar el parámetro de contexto según:

return MultiProvider(
        providers: [              
          ChangeNotifierProvider<WhatEver>(create: (context) => WhatEver()),
          ChangeNotifierProxyProvider<AuthProvider, ProductList>(
            create: (ctx) => ProductList(Provider.of<AuthProvider>(ctx, listen: false)),
            update: (_, auth, productList) => productList..reloadList(auth)
          ),
        ],

Existe un patrón al crear cadenas de dependencia CN de objetos inicializables asincrónicamente... pero está fuera del alcance de esta pregunta.



------------------------------------

Tengo un código que hace esto:

ChangeNotifierProxyProvider<AuthService, ProfileService>(
  create: (ctx) => ProfileService(),
  update: (ctx, authService, profileService) =>
      profileService..updateAuth(authService),
),

My ProfileService() no depende de que AuthService esté disponible cuando se construye. El código funciona bien :)

La documentación de ChangeNotifierProxyProvider describe explícitamente este enfoque:

Observe cómo MyChangeNotifier no recibe MyModel en su constructor ya no. Ahora se pasa a través de un método/definidor personalizado.

1

El enlace de Eduardo a otra respuesta era correcto. ChangeNotifierProxyProvider es vago. Si lazy se establece en falso, se inicia durante la compilación.

- usuario1086500

27/03/2021 a las 23:47

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare