Flutter数据响应式编程插件observable_ish的使用

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

Flutter数据响应式编程插件observable_ish的使用

observable_ish简介

observable_ish 是一个用于编写优雅的跨平台客户端应用程序的轻量级非侵入式响应式框架,它使用Dart的异步 Stream 来发出和监听变化。该库提供了以下功能:

  • Reactive Values:响应式的简单值封装。
  • Reactive Lists:响应式的列表。
  • Reactive Sets:响应式的集合。
  • Reactive Maps:响应式的映射。
  • Event emitter:事件发射器。

这些功能使得UI可以自动更新,并且可以通过事件发射器将事件传递给父组件。

Reactive values(响应式值)

获取和设置值

RxValue 可以用来封装一个简单的可观察值。它暴露了一个 value 字段来获取和设置当前值。

void main() {
  final rxInts = RxValue<int>(initial: 5);
  int got = rxInts.value; // 获取当前值
  print(got); // 输出: 5
  rxInts.value = 10;      // 设置当前值
  print(rxInts.value); // 输出: 10
}

当设置的值与现有值不同时,会通过多种方式通知变化。

监听变化

RxValue 提供了几种灵活的方式来监听变化:

  • onChange:记录变化。
  • values:新的值流。
  • listen:带有新值的回调函数。
void main() {
  final rxInts = RxValue<int>(initial: 5);
  print(rxInts.value);  // 输出: 5
  rxInts.values.listen((int v) => print('New value: $v'));  // 输出: 5, 20, 25
  rxInts.value = 20;
  rxInts.value = 25;
}

绑定到一个值

RxValue 可以绑定到一个 Stream 或另一个 RxValue,当源 Stream 发出或 RxValue 改变时,它的值也会改变。

void main() {
  final textBox = RxValue<String>();
  final checkBox = RxValue<bool>(initial: false);
  
  textBox.bindStream(checkBox.map((bool v) => v ? 'Female' : 'Male'));
  checkBox.value = true;
  print(textBox.value); // 输出: Female
  checkBox.value = false;
  print(textBox.value); // 输出: Male
}

完整示例

import 'package:observable_ish/observable_ish.dart';

void main() async {
  final rxInts = RxValue<int>(initial: 5);
  print(rxInts.value); // 输出: 5
  rxInts.value = 10;
  rxInts.value = 15;
  rxInts.values.listen((int v) => print('value: $v')); // 输出: 15, 20, 25
  await Future.delayed(Duration(milliseconds: 50));
  rxInts.value = 20;
  rxInts.value = 25;
}

Composite reactive objects(复合响应式对象)

observable_ish 设计为非侵入式的,其理念是将模型和其响应式版本分离到不同的类中。

class RxUser {
  final name = RxValue<String>();
  final age = RxValue<int>();
}

class User {
  final rx = RxUser();

  User({String name, int age}) {
    this.name = name;
    this.age = age;
  }

  String get name => rx.name.value;
  set name(String value) => rx.name.value = value;

  int get age => rx.age.value;
  set age(int value) => rx.age.value = value;
}

void main() {
  final user = User(name: 'Messi', age: 30);
  user.age = 31;
  print(user.age);  // 输出: 31
  print('---------');
  user.age = 32;
  user.rx.age.listen((int v) => print(v));  // 输出: 32, 33, 34, 35
  user.age = 33;
  user.age = 34;
  user.age = 35;
}

Event emitter(事件发射器)

Emitter 提供了一个简单的接口来发出和监听事件,设计上与 RxValue 协同工作以提高生产力。

监听事件

Emitter 提供了多种方式来监听事件:

  • on:在事件发生时执行回调。
  • listen:类似于 Stream
  • asStream:将事件作为 Stream 获取。

管道事件

pipeTopipeToValue 方法可以将事件管道到另一个 EmitterRxValue

发出事件

emitemitOneemitAllemitStreamemitRxValue 提供了多种方式来发出事件。

Reactive Lists(响应式列表)

RxList 在元素添加、移除、清空或设置时通知变化。

更新 RxList

RxList 实现了 Dart 的 List 接口,并提供了一些方便的方法来根据条件添加元素。

void main() {
  final rxInts = RxList<int>();
  rxInts.onChange.listen((c) => print(c.element)); // 输出: 5
  rxInts.addIf(5 < 10, 5);
  rxInts.addIf(5 > 9, 9);
}

监听变化

onChange 暴露了一个记录 List 变化的 Stream

Reactive Sets(响应式集合)

RxSet 在元素添加或移除时通知变化。

更新 RxSet

RxSet 实现了 Dart 的 Set 接口,并提供了一些方便的方法来根据条件添加元素。

void main() {
  final rxInts = RxSet<int>();
  rxInts.onChange.listen((c) => print(c.element)); // 输出: 5
  rxInts.addIf(5 < 10, 5);
  rxInts.addIf(5 > 9, 9);
}

监听变化

onChange 暴露了一个记录 Set 变化的 Stream

Reactive Maps(响应式映射)

RxMap 在元素添加、移除、清空或设置时通知变化。

更新 RxMap

RxMap 实现了 Dart 的 Map 接口,并提供了一些方便的方法来根据条件添加元素。

监听变化

onChange 暴露了一个记录 Map 变化的 Stream

通过这些功能,observable_ish 插件可以帮助开发者更轻松地管理状态和事件,从而构建更加动态和响应式的Flutter应用。


更多关于Flutter数据响应式编程插件observable_ish的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据响应式编程插件observable_ish的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用observable_ish插件来实现数据响应式编程的代码案例。

observable_ish 是一个轻量级的 Flutter 插件,它允许你创建可观察的对象,并在这些对象的数据发生变化时自动通知监听器。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 observable_ish 依赖:

dependencies:
  flutter:
    sdk: flutter
  observable_ish: ^2.0.0  # 请根据最新版本进行调整

然后运行 flutter pub get 来获取依赖。

2. 创建可观察对象

接下来,你可以使用 observable_ish 来创建可观察的对象。例如,我们创建一个简单的 Person 类:

import 'package:observable_ish/observable_ish.dart';

class Person extends ObservableObject {
  String name = '';
  int age = 0;

  Person(this.name, this.age);

  set newName(String value) {
    name = value;
    notifyPropertyChange(#name);
  }

  set newAge(int value) {
    age = value;
    notifyPropertyChange(#age);
  }
}

在这个例子中,Person 类继承了 ObservableObject,并且我们为 nameage 属性添加了 setter 方法,在这些 setter 方法中调用 notifyPropertyChange 方法来通知监听器属性已经改变。

3. 使用可观察对象

现在,我们可以在 Flutter 的 Widget 树中使用这个可观察对象,并在数据变化时更新 UI。例如,创建一个简单的界面来显示和编辑 Person 对象的信息:

import 'package:flutter/material.dart';
import 'package:observable_ish/observable_ish.dart';
import 'person.dart'; // 假设你的 Person 类定义在这个文件中

void main() {
  final person = Person('Alice', 30);

  runApp(MyApp(person: person));
}

class MyApp extends StatelessWidget {
  final Person person;

  MyApp({required this.person});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Observable Example'),
        ),
        body: ObservableBuilder<Person>(
          observable: person,
          builder: (context, person) {
            return Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                children: <Widget>[
                  TextField(
                    decoration: InputDecoration(labelText: 'Name'),
                    onChanged: (value) {
                      person.newName = value;
                    },
                    controller: TextEditingController(text: person.name),
                  ),
                  SizedBox(height: 16),
                  TextField(
                    decoration: InputDecoration(labelText: 'Age'),
                    keyboardType: TextInputType.number,
                    onChanged: (value) {
                      if (int.tryParse(value) != null) {
                        person.newAge = int.parse(value);
                      }
                    },
                    controller: TextEditingController(text: person.age.toString()),
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );
  }
}

在这个例子中,我们使用了 ObservableBuilder 组件来监听 person 对象的变化。当 person 对象的 nameage 属性发生变化时,ObservableBuilder 会自动调用 builder 函数来重建 UI。

注意,我们使用 TextEditingController 来管理 TextField 的文本,并在 onChanged 回调中更新 person 对象的属性。这样做可以确保 TextField 的显示与 person 对象的状态保持同步。

总结

通过上述步骤,你可以使用 observable_ish 插件在 Flutter 项目中实现数据响应式编程。这个插件提供了一种轻量级的方式来创建可观察的对象,并在对象状态变化时自动更新 UI。

回到顶部