[英]Using Scoped Model to maintain app state in flutter
我需要帮助为我的应用程序创建架构。 我正在使用Flutter和scoped_model来维护状态。
这是一个具有登录功能的应用程序,它在应用程序的一个部分中显示新闻,并显示照片库等。 我想将整个事情分成不同的模型。 保存登录状态的LoginModel(如用户名,令牌,名称等)。 包含从API检索的新闻的NewsModel。 GalleryModel用于保存照片的名称等。我不确定这是否是使用scoped_model维护状态的最佳实践。
例如,如果文本框依赖于LoginModel和NewsModel,该怎么办? 我不确定,但我想从两个独立的模型中检索状态是不可能的。 此外,我维护单独的模型以保持状态的主要原因是我不希望在我带来新闻时刷新应用程序的登录部分。 我猜这就是我将整个状态放在一个模型中的方式。
scoped_model
库旨在同时处理多个模型。 这是ScopedModel
和ScopedModelDescendant
是泛型并具有类型参数的部分原因。 您可以使用ScopedModel<LoginModel>
和ScopedModel<NewsModel>
ScopedModel<LoginModel>
在Widget树顶部附近定义多个模型,然后使用ScopedModelDescendant<LoginModel>
和ScopedModelDescendant<NewsModel>
ScopedModelDescendant<LoginModel>
使用树中较低的模型。 后代将根据其类型参数寻找合适的模型。
我敲了一个简单的例子。 以下是模型:
class ModelA extends Model {
int count = 1;
void inc() {
count++;
notifyListeners();
}
}
class ModelB extends Model {
int count = 1;
void inc() {
count++;
notifyListeners();
}
}
以下是我在应用中显示的内容:
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()),
),
],
),
);
},
),
),
),
)
它似乎工作得很好。 非嵌套方法也适用:
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()),
),
),
],
),
),
)
我想在ScopedModel上给你一个简单的例子。
pubspec.yaml文件必须包括: -
dependencies:
scoped_model: ^1.0.1
然后,
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.