notifyListeners 后列表被清空

List is emptied after notifyListeners

我有一个怪怪的,一直摸不着头脑

我有一个 属性 在我的一个 class 上使用提供商 除了这种特殊情况,我可以很好地访问和修改:

我将产品添加到 _products 列表

_products.add(product);
notifyListeners();

此时产品是 class 具有以下属性

name String;
id String;
ingredients List<String>;

假设产品是

final product = Product(name:'milk', id:1, ingredients:['milk']);

这个元素被添加到列表中,我可以在调试中看到现在 _products 确实是一个列表,里面有 1 个项目并且所有属性都是正确的

一旦它通知听众他们获得了 _products 的新值,我可以看到他们收到新值就好了,除了由于某些奇怪的原因成分列表是空的!

[ Product(name:'milk', id:1, ingredients:[]) ] // _products for representation purposes

我只是在通知之前验证了 _products 的值,它的成分 属性 正确,然后在通知之后,属性 变成了一个空列表 其他 2 个属性 id 和 name 已正确更新

我已经非常彻底地检查过了,我没有代码可以修改 _products 其他地方

由于我们不知道您对 Product 和 ProductList 的实现细节,因此我在这种情况下自己创建了一个示例。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class Product
{
  final String name;
  final String id;
  final List<String> ingredients;
  
  const Product({
    required this.name,
    required this.id,
    required this.ingredients
  });
  
}

class ProductList extends ChangeNotifier
{
  final _products = <Product>[];
  
  void add(Product product)
  {
    _products.add(product);
    notifyListeners();
  }

  Iterable<Product> get products => _products;
  
}

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => ProductList()),
      ],
      child: MaterialApp(
        title: 'Flutter Demo',
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: const MyHomePage(title: 'Flutter Demo Home Page'),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  const MyHomePage({
    Key? key,
    required this.title,
  }) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  void _incrementCounter() {
    context.read<ProductList>().add(const Product(name: 'Product 1', id: '1234', ingredients: ['Hello', 'There']));
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: const SafeArea(
        child: Products(),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

class Products extends StatelessWidget {
  const Products({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        for(var product in context.watch<ProductList>().products)
          ListTile(
            leading: Text(product.id),
            title: Text(product.name),
            subtitle: Text(product.ingredients.join(', ')),
          ),
      ]
    );
  }
}

您可以在Dart Pad. Hope this helps. Please refer to How to create a Minimal, Reproducible Example上查看。

抱歉,这根本不是提供商的问题

发生的事情是,当我将产品分配给产品列表时,成分列表是一个参考,在使用后被控制器清除,所以在代码中是这样的:


List<String> ingredients = [];

void onAddIngredient(){
  ingredients.add(ingredientController.text);
}

void onSubmit(){

  final myNewProduct = Product(
    name: nameController.text,
    id: idController.text, 
    ingredients:ingredients
  )

  providerAction(myNewProduct); // This is where it gets added to _products

  nameController.clear();
  idController.clear();
  ingredientController.clear();
  ingredients.clear(); // This was the problem where I was deleting the reference 
}