当嵌套对象内的属性更改时,提供程序不会更新

发布于 2025-01-15 04:35:37 字数 1631 浏览 3 评论 0原文

我有一个初始化多个对象的模型。每当其中一个对象内的属性发生更改时,用户界面就不会重建。我负责使用 Equatable 覆盖对象的哈希和 ==,以便提供程序应该检测到更改。以下是显示重要部分的代码示例:

class Tag extends ChangeNotifier with EquatableMixin {
  Tag(this._title, this._value, this._selected);

  final String _title;
  String _value;
  bool _selected;

  @override
  List<Object> get props => [_title, _value, _selected];

  String get title => _title;

  String get value => _value;
  set value(String newValue) {
    _value = newValue;
    notifyListeners();
  }

  bool get selected => _selected;
  set selected(bool newValue) {
    _selected = newValue;
    notifyListeners();
  }
}

class TagModel extends ChangeNotifier {
  TagModel() {
    _tag1.addListener(notifyListeners);
    _tag2.addListener(notifyListeners);
    _tag3.addListener(notifyListeners);
  }

  final Tag _tag1 = Tag("", "", false);
  final Tag _tag2 = Tag("", "", false);
  final Tag _tag3 = Tag("", "", false);

  Tag get tag1 => _tag1;
  Tag get tag2 => _tag2;
  Tag get tag3 => _tag3;
  

  //this function does not trigger a widget rebuild
  void loadTags() {
    _tag1.title = "tag 1";
    _tag2.title = "tag 2";
    _tag3.title = "tag 3";
  }
}

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

  @override
  Widget build(BuildContext context) {
    //this does not change when loadTags function is called 
    final tag1 = context.select((TagModel tagModel) => tagModel.tag1)
    return Container(
      .
      .
      .
      ElevatedButton(
        onPressed: () => context.read<TagModel>().loadTags(),
      )
    );
  }
}

I have a model which initializes multiple objects. Whenever a property inside one of the objects changes, the ui does not rebuild. I took care of overwriting the hash and == of the objects using Equatable so provider should detect the changes. Here is a sample from the code that shows the important parts:

class Tag extends ChangeNotifier with EquatableMixin {
  Tag(this._title, this._value, this._selected);

  final String _title;
  String _value;
  bool _selected;

  @override
  List<Object> get props => [_title, _value, _selected];

  String get title => _title;

  String get value => _value;
  set value(String newValue) {
    _value = newValue;
    notifyListeners();
  }

  bool get selected => _selected;
  set selected(bool newValue) {
    _selected = newValue;
    notifyListeners();
  }
}

class TagModel extends ChangeNotifier {
  TagModel() {
    _tag1.addListener(notifyListeners);
    _tag2.addListener(notifyListeners);
    _tag3.addListener(notifyListeners);
  }

  final Tag _tag1 = Tag("", "", false);
  final Tag _tag2 = Tag("", "", false);
  final Tag _tag3 = Tag("", "", false);

  Tag get tag1 => _tag1;
  Tag get tag2 => _tag2;
  Tag get tag3 => _tag3;
  

  //this function does not trigger a widget rebuild
  void loadTags() {
    _tag1.title = "tag 1";
    _tag2.title = "tag 2";
    _tag3.title = "tag 3";
  }
}

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

  @override
  Widget build(BuildContext context) {
    //this does not change when loadTags function is called 
    final tag1 = context.select((TagModel tagModel) => tagModel.tag1)
    return Container(
      .
      .
      .
      ElevatedButton(
        onPressed: () => context.read<TagModel>().loadTags(),
      )
    );
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

放手` 2025-01-22 04:35:37

您是否尝试在方法末尾添加对 NotifyListeners() 的调用?

did you try adding a call to NotifyListeners() at the end of the method?

一指流沙 2025-01-22 04:35:37

当按下提升按钮时,尝试使用 Statefull Widget 而不是 Stateless 而非 setState。例如

class TagPane extends StatefullWidget {
  const TagPane({Key? key}) : super(key: key);
  
  @override
  _TagPaneState createState() => _TagPaneState();
}

class _TagPaneState extends State<TagPane>{
  @override
  Widget build(BuildContext context) {
    //this does not change when loadTags function is called 
    final tag1 = context.select((TagModel tagModel) => tagModel.tag1)
    return Container(
      .
      .
      .
      ElevatedButton(
        onPressed: () => setState(() { 
          context.read<TagModel>().loadTags());
        ),
      )
    );
  }
}

Try using Statefull Widget instead of Stateless than setState when pressing Elevated button. e.g

class TagPane extends StatefullWidget {
  const TagPane({Key? key}) : super(key: key);
  
  @override
  _TagPaneState createState() => _TagPaneState();
}

class _TagPaneState extends State<TagPane>{
  @override
  Widget build(BuildContext context) {
    //this does not change when loadTags function is called 
    final tag1 = context.select((TagModel tagModel) => tagModel.tag1)
    return Container(
      .
      .
      .
      ElevatedButton(
        onPressed: () => setState(() { 
          context.read<TagModel>().loadTags());
        ),
      )
    );
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文