使用Scoped模型来维持扑动中的应用状态

Pon*_*gal 5 flutter scoped-model

我需要帮助为我的应用程序创建架构.我正在使用Flutter和scoped_model来维护状态.

这是一个具有登录功能的应用程序,它在应用程序的一个部分中显示新闻,并显示照片库等.我想将整个事物分成不同的模型.保存登录状态的LoginModel(如用户名,令牌,名称等).包含从API检索的新闻的NewsModel.GalleryModel用于保存照片的名称等.我不确定这是否是使用scoped_model维护状态的最佳实践.

例如,如果文本框依赖于LoginModel和NewsModel,该怎么办?我不确定,但我想从两个独立的模型中检索状态是不可能的.此外,我维护单独的模型以保持状态的主要原因是我不希望在我带来新闻时刷新应用程序的登录部分.我猜这就是我将整个状态放在一个模型中的方式.

Red*_*don 10

scoped_model库旨在同时处理多个模型.这是因为ScopedModel并且ScopedModelDescendant是泛型并且具有类型参数的部分原因.您可以使用ScopedModel<LoginModel>和在Widget树顶部附近定义多个模型ScopedModel<NewsModel>,然后使用ScopedModelDescendant<LoginModel>和使用树中较低的模型ScopedModelDescendant<NewsModel>.后代将根据其类型参数寻找合适的模型.

我敲了一个简单的例子.以下是模型:

class ModelA extends Model {
  int count = 1;
  void inc() {
    count++;
    notifyListeners();
  }
}

class ModelB extends Model {
  int count = 1;
  void inc() {
    count++;
    notifyListeners();
  }
}
Run Code Online (Sandbox Code Playgroud)

以下是我在应用中显示的内容:

ScopedModel<ModelA>(
  model: ModelA(),
  child: ScopedModel<ModelB>(
    model: ModelB(),
    child: ScopedModelDescendant<ModelA>(
      builder: (_, __, a) => ScopedModelDescendant<ModelB>(
        builder: (_, __, b) {
          return Center(
            child: Column(
              children: [
                GestureDetector(
                  onTap: () => a.inc(),
                  child: Text(a.count.toString()),
                ),
                SizedBox(height:100.0),
                GestureDetector(
                  onTap: () => b.inc(),
                  child: Text(b.count.toString()),
                ),
              ],
            ),
          );
        },
      ),
    ),
  ),
)
Run Code Online (Sandbox Code Playgroud)

它似乎工作得很好.非嵌套方法也适用:

ScopedModel<ModelA>(
  model: ModelA(),
  child: ScopedModel<ModelB>(
    model: ModelB(),
    child: Column(
      children: [
        ScopedModelDescendant<ModelA>(
          builder: (_, __, model) => GestureDetector(
                onTap: () => model.inc(),
                child: Text(model.count.toString()),
              ),
        ),
        SizedBox(height: 100.0),
        ScopedModelDescendant<ModelB>(
          builder: (_, __, model) => GestureDetector(
                onTap: () => model.inc(),
                child: Text(model.count.toString()),
              ),
        ),
      ],
    ),
  ),
)
Run Code Online (Sandbox Code Playgroud)


Div*_*mar 5

我想给您一个关于ScopedModel的简单示例。

pubspec.yaml文件必须包含:-

dependencies:
  scoped_model: ^1.0.1
Run Code Online (Sandbox Code Playgroud)

然后,

import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';

void main() => runApp(MyApp());   //main method

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(), //new class MyHomePage
    );
  }
}

//-----------------------------------CounterModel [used by ScopedModel]
class CounterModel extends Model {
  int _counter = 0;
  int get counter => _counter;
  void increment() {
    _counter++;
    notifyListeners();
  }
}
//-----------------------------------ends


//-----------------------------------MyHomePage class
class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return ScopedModel(    // ScopedModel used on top of the widget tree [it is wrapping up scaffold]
      model: CounterModel(), // providing the CounterModel class as model
      child: Scaffold(
        appBar: AppBar(),
        body: Container(
          child: ScopedModelDescendant<CounterModel>(  // ScopedModelDescendant accessing the data through ScopedModel
            builder: (context, _, model) => Text("${model._counter}"), // fetching data from model without thinking of managing any state.
          ),
        ),
        floatingActionButton: ScopedModelDescendant<CounterModel>(
          builder: (context, _, model) => FloatingActionButton(
                onPressed: model.increment, // calling function of model to increment counter
              ),
        ),
      ),
    );
  }
}
//-----------------------------------ends
Run Code Online (Sandbox Code Playgroud)