使用上下文和观察更改模型时,Flutter Provider 不会触发重建

Posted

技术标签:

【中文标题】使用上下文和观察更改模型时,Flutter Provider 不会触发重建【英文标题】:Flutter Provider doesn't trigger rebuild when model is changed with context and watch 【发布时间】:2021-11-12 23:11:10 【问题描述】:

我正在使用 Flutter 的 FutureProvider。这是我的 add_match_screen.dart 文件,在这里我正在启动提供程序以在其他小部件中使用它。


    class _AddMatchScreenState extends State<AddMatchScreen> 
      late Future<List<Team>> _teamsFuture;
    
      @override
      void initState() 
        super.initState();
        _teamsFuture = Team.getAllTeams();
      
    
      @override
      Widget build(BuildContext context) 
        return Layout(
          appBarTitle: 'Add New Match',
          body: FutureProvider<List<Team>>(
            initialData: const [],
            create: (context) => _teamsFuture,
            child: MatchForm(),
          ),
        );
      
    

我正在监听 match_form.dart 文件中的变化。像这样。


    @override
      Widget build(BuildContext context) 
        final _teams = context.watch<List<Team>>();
        
        // print statement here
        print(_items); 

        return Container(
            ....something
        );
    

如果我在这里做一个打印语句,我可以看到它在稍后打印[][instance of Team],这是预期的,对吧?但请仔细阅读以下代码。


    @override
      Widget build(BuildContext context) 
        final teams = context.watch<List<Team>>();
        print(teams);
        return teams.isEmpty
            ? const Loader()
            : Container(
                // something
              );
        

我在这里尝试使用来自提供商的团队。如果团队属性为空,那么我将显示一个加载程序,但我的打印语句运行但我的代码不会重建,它只会永远显示加载程序。那么我在这里做错了什么?

layout.dart 文件


    class Layout extends StatelessWidget 
      final Widget body;
      final String appBarTitle;
      final List<Widget> actions;
    
      const Layout(
        Key? key,
        required this.appBarTitle,
        required this.body,
        this.actions = const [],
      ) : super(key: key);
    
      @override
      Widget build(BuildContext context) 
        return Scaffold(
          resizeToAvoidBottomInset: false,
          drawer: const TheDrawer(),
          appBar: AppBar(
            title: Text(appBarTitle),
            actions: actions,
          ),
          body: body,
        );
      
    

【问题讨论】:

什么是Layout @BalajiRamadoss 更新了问题。 【参考方案1】:

我的猜测是它在小部件树中没有看到变化,也不知道它需要重建。

我会将你的 match_form.dart 更改为有状态的小部件,如果它还没有并使用一个标志,如果团队发生变化,则设置状态并对标志进行比较。

类似这样的:

bool isTeamsEmpty = true;

if(teams.isEmpty == false)

   setState()
   
      isTeamEmpty = false;
   


return isTeamEmpty
            ? const Loader()
            : Container(
                // something
              );

【讨论】:

抱歉,还是不行。谢谢您的回答。但是为什么我需要做这一切呢?不应该看假设当团队改变时重建小部件树?另外,这段代码不漂亮,没有意义,对不起。 @Pranta 不用担心。我是新来的,并且没有使用过“提供者 - 观看”。在您发表评论后阅读文档,我了解您对小部件树所说的内容。学到了一些新东西。谢谢。

以上是关于使用上下文和观察更改模型时,Flutter Provider 不会触发重建的主要内容,如果未能解决你的问题,请参考以下文章

Dart/Flutter 不使用 Inkwell 和手势检测器更改页面

有没有办法在调试 Flutter App 时更改值

ReactiveSwift:使用 MutableProperty 观察托管对象的变化

在上下文中丢弃模型的更改

响应 Django 中的模型更改?

选择可观察的值和文本