Flutter事件总线插件zam_event_bus的使用

Flutter事件总线插件zam_event_bus的使用

事件总线

事件总线是一种状态管理包,用于Flutter应用程序。它通常与zam_event_bus_provider一起使用。

包内包含的组件

事件总线包包括以下核心组件:

  • EventBus
  • EventTransformer

您可以在此处详细了解所有组件:zam_event_bus

如何使用

信息提示: 对于Flutter的使用方法以及如何将EventBus提供给小部件,请参阅zam_event_bus_provider包。

步骤1:创建事件总线
final bus = EventBus([
  EventTransformer.fromFn((HeightSliderDraggedEvent event) => HeightProvidedEvent(event.value)),
  EventTransformer.fromFn((HeightInputTextChangedEvent event) => HeightProvidedEvent(event.value)),
  EventTransformer.fromFn((WeightSliderDraggedEvent event) => WeightProvidedEvent(event.value)),
  EventTransformer.fromFn((WeightInputTextChangedEvent event) => WeightProvidedEvent(event.value)),
  EventTransformer.fromFn((HeightProvidedEvent event) => Bmi.fromHeight(event.value)),
  EventTransformer.fromFn((WeightProvidedEvent event) => Bmi.fromWeight(event.value)),
]);
步骤2:发布事件
bus.publish(HeightSliderDraggedEvent(1.78));
步骤3:选择并监听事件
final sub = bus.select<Bmi>().listen((event) => print(event.value)); // 打印BMI值

要了解更多信息,请查看示例部分,或者检查这些专用的GitHub示例:GitHub示例

状态

Build

贡献者

许可证

BSD 3-Clause License


示例代码

example/lib/main.dart

import 'package:zam_event_bus/zam_event_bus.dart';

void main() async {
  // 创建事件总线,并提供事件转换器。
  // PrepareBmiInputFromHeightUseCase, PrepareBmiInputFromWeightUseCase
  // 和 CalculateBmiUseCase 是事件转换器,它们将一个事件转换为另一个事件。
  final bus = EventBus.withLogger([
    PrepareBmiInputFromHeightUseCase(),
    PrepareBmiInputFromWeightUseCase(),
    CalculateBmiUseCase(),
  ]);

  // 将初始体重和高度值保存到存储中。
  print('初始化:');
  bus.save(BmiInputProvidedEvent(80.0, 1.80));

  print('\n设置监听器:');
  // 监听计算后的BMI。
  final successSub = bus.select<BmiCalculatedEvent>().listen(
        (event) => print('- BMI: ${event.data}'),
      ); // 每次发出时打印BMI值。
  // 监听异常。
  final failureSub = bus.select<BmiCalculateFailedEvent>().listen(
        (event) => print('- 异常: ${event.exception}'),
      ); // 异常发生时打印异常。

  // 从UI发布事件。
  // 在事件之间添加10毫秒的延迟,
  // 以便消息按顺序记录。
  print('\n发布 WeightProvidedEvent(76.0):');
  bus.publish(WeightProvidedEvent(76.0));
  await Future.delayed(Duration(milliseconds: 10));

  print('\n发布 HeightProvidedEvent(-162.4):');
  bus.publish(HeightProvidedEvent(-162.4));
  await Future.delayed(Duration(milliseconds: 10));

  print('\n发布 WeightProvidedEvent(0):');
  bus.publish(WeightProvidedEvent(0));
  await Future.delayed(Duration(milliseconds: 10));

  print('\n发布 HeightProvidedEvent(1.72):');
  bus.publish(HeightProvidedEvent(1.72));
  await Future.delayed(Duration(milliseconds: 10));

  print('\n发布 WeightProvidedEvent(64):');
  bus.publish(WeightProvidedEvent(64));
  await Future.delayed(Duration(milliseconds: 10));

  // 清理
  await successSub.cancel();
  await failureSub.cancel();
  // await inputSub.cancel();
  await bus.dispose();
}

///
/// 事件
///
class WeightProvidedEvent {
  final double value;

  const WeightProvidedEvent(this.value);
}

class HeightProvidedEvent {
  final double value;

  const HeightProvidedEvent(this.value);
}

class BmiInputProvidedEvent implements UseCaseEvent {
  final double weight;
  final double height;

  const BmiInputProvidedEvent(this.weight, this.height);
}

class BmiCalculatedEvent extends UseCaseSucceededEvent<Bmi> {
  const BmiCalculatedEvent(Bmi data) : super(data);
}

class BmiCalculateFailedEvent extends UseCaseFailedEvent {
  const BmiCalculateFailedEvent(Exception exception) : super(exception);
}

///
/// 异常
///
class InvalidWeightException implements Exception {
  [@override](/user/override)
  toString() => '体重必须为正数';
}

class InvalidHeightException implements Exception {
  [@override](/user/override)
  toString() => '身高必须为正数';
}

///
/// 领域模型
///
class Bmi {
  final double weight;
  final double height;
  late final double value;

  Bmi(this.weight, this.height) {
    if (weight <= 0) throw InvalidWeightException();
    if (height <= 0) throw InvalidHeightException();
    value = weight / (height * height);
  }

  [@override](/user/override)
  toString() => value.toStringAsFixed(2);
}

///
/// 每当接收到 WeightProvidedEvent 时,
/// 从事件中提取体重值,
/// 从存储中检索身高值,
/// 并保存并发布 BmiInputSubmittedEvent。
///
class PrepareBmiInputFromWeightUseCase
    extends SavingUseCase<WeightProvidedEvent> {
  [@override](/user/override)
  UseCaseEvent execute(WeightProvidedEvent event, EventBus bus) {
    final weight = event.value;
    final height = bus.selectFromStore<BmiInputProvidedEvent>().height;
    return BmiInputProvidedEvent(weight, height);
  }
}

///
/// 每当接收到 HeightProvidedEvent 时,
/// 从存储中检索体重值,
/// 从事件中提取身高值,
/// 并保存并发布 BmiInputSubmittedEvent。
///
class PrepareBmiInputFromHeightUseCase
    extends SavingUseCase<HeightProvidedEvent> {
  [@override](/user/override)
  UseCaseEvent execute(HeightProvidedEvent event, EventBus bus) {
    final weight = bus.selectFromStore<BmiInputProvidedEvent>().weight;
    final height = event.value;
    return BmiInputProvidedEvent(weight, height);
  }
}

///
/// 每当接收到 BmiInputSubmittedEvent 时,
/// 从事件中提取体重和身高值,
/// 并计算BMI。
/// 如果BMI计算成功,
///   发布带有数据的 BmiCalculatedEvent。
/// 如果BMI计算失败,
///   发布带有异常的 BmiCalculateFailedEvent。
///
class CalculateBmiUseCase extends UseCase<BmiInputProvidedEvent> {
  [@override](/user/override)
  UseCaseEvent execute(BmiInputProvidedEvent event, EventBus bus) {
    print('- 体重: ${event.weight}, 身高: ${event.height}');
    try {
      final bmi = Bmi(event.weight, event.height);
      return BmiCalculatedEvent(bmi);
    } catch (exception) {
      if (exception is InvalidWeightException) {
        return BmiCalculateFailedEvent(exception);
      } else if (exception is InvalidHeightException) {
        return BmiCalculateFailedEvent(exception);
      } else {
        rethrow;
      }
    }
  }
}

更多关于Flutter事件总线插件zam_event_bus的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter事件总线插件zam_event_bus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


zam_event_bus 是一个用于 Flutter 的事件总线插件,它允许你在应用的不同部分之间传递事件。使用事件总线可以帮助你解耦代码,使得不同组件之间的通信更加灵活和高效。

以下是 zam_event_bus 的基本使用步骤:

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  zam_event_bus: ^1.0.0  # 请根据实际情况使用最新版本

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

2. 创建事件

事件是传递数据的载体。你可以创建一个简单的 Dart 类来表示事件:

class MyEvent {
  final String message;

  MyEvent(this.message);
}

3. 注册事件监听器

在需要监听事件的地方,你可以注册一个事件监听器:

import 'package:zam_event_bus/zam_event_bus.dart';

void main() {
  final eventBus = EventBus();

  // 注册事件监听器
  eventBus.on<MyEvent>((event) {
    print('Event received: ${event.message}');
  });

  // 触发事件
  eventBus.fire(MyEvent('Hello, EventBus!'));
}

4. 触发事件

在需要触发事件的地方,你可以使用 eventBus.fire() 方法来发送事件:

eventBus.fire(MyEvent('Hello, EventBus!'));

5. 取消事件监听

如果你不再需要监听某个事件,可以取消监听:

// 注册事件监听器并获取取消监听的回调
final subscription = eventBus.on<MyEvent>((event) {
  print('Event received: ${event.message}');
});

// 取消事件监听
subscription.cancel();

6. 使用 StreamSubscription 进行更复杂的管理

zam_event_bus 也支持使用 StreamSubscription 来管理事件监听,这允许你进行更复杂的操作,如暂停、恢复等:

import 'dart:async';

void main() {
  final eventBus = EventBus();

  // 使用 StreamSubscription 管理事件监听
  StreamSubscription<MyEvent> subscription;

  subscription = eventBus.on<MyEvent>((event) {
    print('Event received: ${event.message}');
    // 取消监听
    subscription.cancel();
  });

  // 触发事件
  eventBus.fire(MyEvent('Hello, EventBus!'));
}

7. 使用 EventBus 单例

为了方便在整个应用中使用同一个 EventBus 实例,你可以将其封装为一个单例:

class EventBusSingleton {
  static final EventBus _eventBus = EventBus();

  static EventBus get instance => _eventBus;
}

// 使用单例
EventBusSingleton.instance.fire(MyEvent('Hello, EventBus!'));

8. 处理多个事件类型

你可以在同一个 EventBus 实例中处理多个事件类型:

eventBus.on<MyEvent>((event) {
  print('MyEvent received: ${event.message}');
});

eventBus.on<AnotherEvent>((event) {
  print('AnotherEvent received: ${event.someData}');
});
回到顶部