【问题标题】:List of Objects In Change Notifier don't update更改通知程序中的对象列表不更新
【发布时间】:2020-09-25 11:03:33
【问题描述】:

我有一个继承自 ChangeNotifier 的对象列表。我删除了这些类型只是为了简化内容。

class TaskListsState with ChangeNotifier {
  List _lists = List();
  _currentList;

  List get lists => _lists;
  get currentList => _currentList;

  set lists(List newValue) {
    this._lists = newValue;
    notifyListeners();
  }

  set currentList(newValue) {
    this._currentList = newValue;
    notifyListeners();
  }

  TaskListsState() {
    this._lists = [
      ToDoListState(),
      ToCreateListState(),
      ToDecideListState(),
      BalancedMeListState()
    ];

    this._currentList = this._lists[0];
  }
}

所有对象都继承自一个基类,但一般来说,它们的外观是这样的

class ToCreateListState with ChangeNotifier implements TaskListState {
  String title = "TO CREATE LIST";
  String alias = "tocreate";
  bool _loading = false;
  List<TaskState> _tasks;

  bool get loading => _loading;
  List<TaskState> get tasks => _tasks;

  set tasks(List<TaskState> newValue) {
    this._tasks = newValue;
    notifyListeners();
  }

  set loading(bool newValue) {
    _loading = newValue;
    notifyListeners();
  }

  ToCreateListState();

  removeTask(TaskState task) {
    this._tasks.remove(task);
    notifyListeners();
  }
}

现在,当我更新列表对象之一时,它们不会在 UI 中更新。请问如何解决这个问题?

目前,这是我在视图中使用它的方式:

 MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (context) => TaskListsState(),
        ),

      ],
      child: MaterialApp(
        title: '',
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primarySwatch: Colors.blue,
          fontFamily: 'Montserrat',
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        initialRoute: defaultHome,
        onGenerateRoute: onGenerateRoute,
      ),
    );

然后,当我想使用屏幕中的一项时,我会使用Provider.of&lt;TaskListsState&gt;(context).lists[index].whateverValue =. anotherValue;

但是,它不会更新。

【问题讨论】:

    标签: flutter flutter-layout flutter-dependencies flutter-animation flutter-test


    【解决方案1】:

    当您运行Provider.of&lt;TaskListsState&gt;(context).lists[index].whateverValue =. anotherValue; 时,它不会调用notifyListeners(),因为它不会更新lists 本身。

    您可以简单地在TaskListsState 中创建一个为您进行修改的方法,然后调用notifyListeners()

    class TaskListsState with ChangeNotifier {
    ...
        void updateWhateverValue(int index, dynamic value) {
            lists[index].whateverValue = value;
            notifyListeners();
        }
    ...
    }
    

    您应该将dynamic 替换为您拥有的对象。

    【讨论】:

    • 好的,我现在试试
    • 但是如果我有深度嵌套的对象,这不是理想的……那我该怎么办?
    • 或者更好的是,如果我有多种方法可以实现(我的情况)。那我该怎么办?
    • 您也可以将这些对象设为ChangeNotifier,并在需要的地方提供它们,可能在某种列表中。 Flutter 团队进行了一场精彩的演讲来解释这一点:youtu.be/d_m5csmrf7I?t=1456
    • 我现在就去看看。谢谢
    【解决方案2】:

    这里有另一种解释: 想象一下我们有这个类

    class Products with ChangeNotifier
    {
    
    List<String> prods =new List() :
    
    List<String> getProds => prods;
    
    Void addprod() 
    {
    prods.add('chocolate');
    prods.add('beer');
    notifyListeners();
    } 
    
    Products()
    {
    addprod();
    }
    
    
    } 
    
    

    所以我们有一个已经有两个产品的类产品。

    删除产品的情况,如果我们调用

    Provider.of&lt;Products&gt;(context)().products.remove('beer')

    Beer 将被删除,但所有其他消费者不会收到通知,因为 remove 是一个预定义的函数,并且在 Products 类中不作为通知程序存在。

    确保每次调用函数时,它实际上是在更新数据模型类中的某些内容,以便您注意到变化。

    希望能阐明您的愿景。

    【讨论】:

    • 这不适用于嵌套对象。感谢您的尝试,但第一个答案中提供的 youtube 视频对我有用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-12
    • 2018-01-28
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    相关资源
    最近更新 更多