首页 > 解决方案 > 如何为小部件(视图)启动 ViewModel

问题描述

所以我正在编写一个利用 MVVM 架构的 Flutter 应用程序。我有一个带有 ValueNotifiers 的每个屏幕(小部件)的 viewModel,我想为该视图启动 viewModel。现在大多数指南都建议使用 Provider 方法,但是当我可以正常启动它时为什么要提供它。

代码:

class FooModel{
  final ValueNotifier<bool> _active = ValueNotifier<bool>(false);
  ValueNotifier<bool> get active => _active;

  FooModel(){_active = false;}
  doSomething(){_active=!_active}
}

我想做的事:

  @override
  Widget build(BuildContext context) {
    _viewModel = FooModel();
    return Scaffold(
      body:ValueListenableBuilder<bool>(
          valueListenable: _viewModel.active,
          builder : (context,value,_){
            if(value)return(Text("active");
            return Text("unactive");
          }

      ) 
  }

建议:

  Widget build(BuildContext context) {
    return Provider<FooModel>(
      create: (_) => FooModel(),
      builder: (context, child) {
        final vm = Provider.of<FooModel>(context);
        return ValueListenableBuilder<bool>(
            valueListenable: vm.active,
            builder: (context, value) {
              if (value) return Text("active");
              return Text("unactive");
            });
      },
   );
 }

现在我明白我的建议是在每次构建时创建 viewModel,但这应该只在加载屏幕时发生,这要归功于 ValueNotifier,所以它很好。我想我只是不明白提供 viewModel 的价值。

标签: flutter

解决方案


Flutter 有不同的意识形态。是的,您可以创建价值通知器,这样做很好,但只是考虑更大的图景。检查您要调用 API 的流程,然后对其执行解析和过滤,您在屏幕上有 2 个视图来显示相同​​的数据,一个是展示数据,另一个是与数据交互,此更新需要反映在展示的数据上。

要做到这一点,我们需要做什么?

  1. 在包含两个屏幕小部件的类级别创建 valuenotifier。
  2. 在类级别调用 API 和过滤代码。
  3. 将此 valuenotifier 传递给两个屏幕小部件,您可能会问为什么对?好吧,因为一个类需要更新其他类小部件。这只是将更新推送到 valuenotifier 的一种方法是对象本身。所以你需要在两个类中传递这个 valuenotifier。
  4. 一旦你这样做并且更新已经同步,如果任何 setState 已被调用到包含这两个小部件的主小部件,那么你需要再次执行所有这些操作。
  5. 还会有多个 valuenotifier 实例,这很糟糕,因为 valuenotifier 是一个流,一旦你完成了流,你需要关闭你的流,所以你需要在主窗口小部件上的任何 setState 事件中关闭你的流的逻辑。

提供者到底是什么?它是如何工作的?好吧,提供者是一个更改通知程序类,当您调用 notifyDataChanged 或 notify 方法时,它会调用 setState。这会触发正在侦听该数据更改的小部件状态更改。并且该小部件得到重建。对于 Bloc、ScopedBloc 或任何小部件(如 streamBuilder 或 ValueListenableBuilder)中的每个状态管理库,这都是相同的逻辑。

在 Flutter 中,如果你想改变数据,你只需要调用 setState。只是为了可测试、更具可读性和可维护性,我们将要做的是将逻辑分离到不同的文件中,就像我们在 Android 或 iOS 中所做的那样,这就是这种类型的库出现的地方,以减少我们再次输入代码的头痛并专注于主要任务,即应用程序的功能。

看我们可以创建不同格式的循环

for(int i=0;i<length;i++)
while(i++<length)
for(i in 0...length) 

我们有责任提供干净且易于理解的代码,这样任何其他开发人员都不需要因为无法理解我们的代码而删除所有代码。

开发中没有对错之分。这是什么更方便或更有意义的问题。像 int i 没有意义,但如果我们用 index 或 listIndex 替换它,它会。

另外,要提到的一件事是您正在做的是创建一个与 bloc 模式相同的模型。所以你已经完成了一半。您只需要从模型检查块和您将理解的其他模式中调用状态更改。


推荐阅读