首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不为集合工作的ChangeNotifier (列表)

不为集合工作的ChangeNotifier (列表)
EN

Stack Overflow用户
提问于 2022-01-04 09:03:41
回答 1查看 329关注 0票数 1

我在我的混和颤振项目中使用了状态管理。

我有一个模型类,它管理对象列表及其排序顺序。排序顺序只是一个带有字段名称的String,应该使用该字段进行排序。

UI是一个包含ListView.separatedSlidable。您可以修改、复制或删除列表中的条目。在列表的顶部是DropDownButton,它允许选择一个字段来对列表进行排序。

以下是屏幕的相关部分:

Widget是无状态的,在build方法中有两个观察者,如下所示:

代码语言:javascript
复制
var ccOverviewList = watchOnly((CcListManager ccListManager) => ccListManager.creditCardOverviewList);
var sortProperty = watchOnly((CcListManager ccListManager) => ccListManager.sortProperty);

当用户选择一个不同的属性对列表进行排序时,我会在我的模型类中调用一个方法,然后调用notifyListener。这对于存储的排序属性很好,但是当列表被修改时不起作用。onChangedDropDownButton处理程序如下所示:

代码语言:javascript
复制
      onChanged: (String? newValue) {
        GetIt.I<CcListManager>().sortProperty = newValue!;
      },

模型中的实现(CcListManager):

代码语言:javascript
复制
class CcListManager extends ChangeNotifier {
  var _sortProperty = 'Name';
  set sortProperty(String val) {
    _sortProperty = val;
    _sortCreditCardOverview();
    debugPrint('Notifying listeners...');
    notifyListeners();
  }
  String get sortProperty => _sortProperty;

  List<CreditCardOverview> _creditCardOverviewList = /*<CreditCardOverview>*/[];
  set creditCardOverviewList(List<CreditCardOverview> val) {
    _creditCardOverviewList = val;
    debugPrint('Notifying listeners...');
    notifyListeners();
  }
  List<CreditCardOverview> get creditCardOverviewList => _creditCardOverviewList;


}

_sortProperty更改并调用notifyListeners时,我可以看到调用了带有ListView的小部件的.build()方法。

,但是当我修改列表_creditCardOverviewList上的时,build()方法是而不是调用的,因此列表不会更新。下面是delete操作的代码:

代码语言:javascript
复制
  void removeCreditCardFromOverview(String creditCardId) {
    debugPrint('CcListManager.removeCreditCardFromOverview()');
    var pos = _creditCardOverviewList.indexWhere((element) => element.creditCardLocalId == creditCardId);
    if (pos >= 0) {
      _creditCardOverviewList.removeAt(pos);
      debugPrint('Notifying listeners...');
      notifyListeners();
    }
  }

我不知道为什么适用于原语类型,但不适用于集合。在我看来,在notifyListeners()内部,它会检查属性的值是否真的发生了变化,不知道是否承认,列表中的元素或其长度已经改变,因此不会通知已注册的侦听器。

我也不知道这是get_it / get_it_mixin插件的问题还是ChangeNotifier / notifyListeners的问题。

知道这里出了什么问题吗?

EN

回答 1

Stack Overflow用户

发布于 2022-01-05 09:44:44

好的,我自己发现了问题。这也是一年多前使用提供商的人经历过的事情。它看起来像是notifyListeners检查这个值是否真的改变了。看起来他们依赖于==运算符来获取列表。这个操作符做了,而不是,对列表中的每个成员进行了深入的比较。因此,解决方案是使用.from()命名构造函数重新创建整个列表。那么它就会像预期的那样工作。因此,上述删除代码需要更改如下:

代码语言:javascript
复制
void removeCreditCardFromOverview(String creditCardId) {
    var pos = _creditCardOverviewList.indexWhere((element) => element.creditCardLocalId == creditCardId);
    if (pos >= 0) {
      _creditCardOverviewList.removeAt(pos);
      creditCardOverviewList = List.from(_creditCardOverviewList);
    }
  }

notifyListenerscreditCardOverviewList的设置者调用。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70576332

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档