Flutter作用域隔离插件scoped的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter作用域隔离插件scoped的使用

标题

scoped

内容

一个非常实用的方式来访问 你的服务和状态,目标只有一个:

简单性

scoped 包含了三个主要组件:

  • Store - 一个简单的的服务定位器
  • Scope - 一个继承自 widget 来帮助获取到你的 store
  • Reactive - 一个简单的方式来为你的模型添加响应性
  • Ref<T> - 可响应的值
  • Refs<T> - 可响应的列表

希望你喜欢它。

示例

dependencies:
  scoped: ^2.0.0
import 'package:scoped/scoped.dart';
import 'package:scoped/material.dart';

class Service {
  final Ref<String> foo = Ref();
  final Refs<String> foos = Refs();

  final String name;
  Service(this.name);

  change() {
    foo.value = 'bar';
  }
}

void main() => runApp(Scope(
  store: Store()
    ..add(Service('a great service')),
  child: YourApp()));
  
class YourApp extends StatelessWidget {
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text(context.get<Service>().name),
        FlatButton(
          child: Text("Change"),
          onPressed: () => context.get<Service>().change(),
        ),
        context.get<Service>().foo.bindValue((_, v) => Text(v))
      ],
    );
  }
}

示例代码

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

void main() => runApp(Scope(store: Store()..add(AppState()), child: MyApp()));

class AppState {
  final Refs&lt;int&gt; lines = Ref();
  final Ref ref&lt;int&gt; counter = Ref(0);

  save() {
    lines.add(counter.value);
    counter.value = 0;
  }
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: ListView(
          padding: EdgeInsets.only(left: 12, top: 8, right: 24),
          children: [
            Text(
              'You have pushed the button this many times:',
            ),
            context
                .get<AppState>()
                .counter
                .bindValue((context, counter) =&gt; Text(
                      '$counter',
                      style: Theme.of(context).textTheme.bodyText1,
                    )),
            Divider(),
            context.get<AppState>().lines.bind((context, lines) =&gt; ListBody(
                  children: &lt;Widget&gt;[
                    if (lines.isNotEmpty) Text('History'),
                    ListView.builder(
                      itemBuilder: (context, index) =&gt; Text('${lines[index]}'),
                      itemCount: lines.length,
                      shrinkWrap: true,
                      physics: ClampingScrollPhysics(),
                    )
                  ],
                ))
          ]),
      bottomNavigationBar: Material(
        elevation: 1,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: &lt;Widget&gt;[
            TextButton(
                child: Icon(Icons.add),
                onPressed: () =&gt; context.get<AppState>().counter.value++),
            TextButton(
              child: Icon(Icons.save),
              onPressed: context.get<AppState>().save,
            ),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter作用域隔离插件scoped的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter作用域隔离插件scoped的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,scoped_model 是一个常用的状态管理库,它允许你在应用中创建和管理全局或局部状态,并通过提供作用域(scope)来隔离这些状态。尽管 scoped_model 已经逐渐被 provider 等更现代的库所取代,但它仍然在一些项目中很有用。以下是如何在Flutter中使用 scoped_model 的一个简单示例。

首先,确保你已经在 pubspec.yaml 文件中添加了 scoped_model 依赖:

dependencies:
  flutter:
    sdk: flutter
  scoped_model: ^1.0.1  # 请检查最新版本号

然后运行 flutter pub get 来安装依赖。

1. 创建一个 Model

Model 类将包含你的应用状态和数据。在这个例子中,我们将创建一个简单的计数器模型。

import 'package:scoped_model/scoped_model.dart';

class CounterModel extends Model {
  int _counter = 0;

  int get counter => _counter;

  void increment() {
    _counter++;
    notifyListeners();  // 通知监听器状态已更改
  }
}

2. 包装应用与 ScopedModel

在你的主应用入口(通常是 main.dart),使用 ScopedModel 包装你的应用,并提供一个 CounterModel 实例。

import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import 'counter_model.dart';  // 假设你的 Model 类在这个文件中

void main() {
  runApp(
    ScopedModel<CounterModel>(
      model: CounterModel(),
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Scoped Model Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ScopedModelDescendant<CounterModel>(
        builder: (context, child, model) {
          return MyHomePage(counter: model.counter, onIncrement: model.increment);
        },
      ),
    );
  }
}

3. 创建 UI 并使用 ScopedModelDescendant

在需要使用 CounterModel 的地方,使用 ScopedModelDescendant 来访问模型。

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

class MyHomePage extends StatelessWidget {
  final int counter;
  final VoidCallback onIncrement;

  MyHomePage({Key key, @required this.counter, @required this.onIncrement})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Scoped Model Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: onIncrement,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

总结

以上代码展示了如何在Flutter中使用 scoped_model 来管理应用状态。CounterModel 包含了状态逻辑,ScopedModel 包装了应用并提供模型实例,而 ScopedModelDescendant 用于在UI中访问和响应模型状态的变化。

请注意,虽然 scoped_model 仍然可以使用,但 provider 提供了更强大的功能和更好的性能,特别是在大型应用中。如果你正在开始一个新项目,可能要考虑使用 provider 或其他现代状态管理库。

回到顶部