Flutter事件总线插件event_bus_arch的使用
Flutter事件总线插件event_bus_arch的使用
关于
这个包是事件驱动架构的一部分,提供发送、监听、处理和接收事件的功能。
V2 简单使用
EventBus在V2中有三个主要方法:send
、listen
和lastData
。
void main() async {
/// EventBusIsolate由主隔离区和工作隔离区两部分组成。
/// 它们之间交换EventDTO和处理程序的工作结果。
EventBusIsolate isolateBus = EventBusIsolate(onInit: _initIsolate);
await isolateBus.waitInit;
/// 在主隔离区监听来自工作隔离区的事件
isolateBus.listen<String>().listen((event) {
print('event from isolate: $event');
});
print('result: ${await isolateBus.send(10)}');
print('result: ${await isolateBus.send(11)}');
await Future.delayed(Duration(seconds: 1));
}
/// 此函数在隔离区运行。我们等待类型为<int>的事件,并返回一个字符串结果
void _initIsolate(EventBus bus) {
/// 所有的EventBus都实现了EventBusHandlers接口
/// 设置事件类型为<int>的处理程序
(bus as EventBusHandlers).setHandler<int>(handler: (dto, lastData) async {
// 发送结果到主线程
dto.completer?.complete(dto.data.toString());
// 发送事件<String>
bus.send(dto.data.toString());
});
}
V1 简单使用
事件(EventDTO)由三部分组成:头部(主题)、唯一标识符和数据。主题由传输对象的类型(必需)和事件名称组成。
EventBus bus = EventBus();
//----- 不使用EventDTO
/// listenEvent返回Stream
/// 主题 = 'int'
/// bus.listenEvent<int>()! 可以返回null,如果你设置了前缀,因为bus会搜索其他带有前缀的EventBus
bus.listenEvent<int>()!.listen((event) => print('int event:$event'));
/// 主题 = 'int^test'
bus.listenEvent<int>(eventName: 'test')!.listen((event) => print('int^test event:$event'));
/// 主题 = 'int'
bus.send<int>(1); //'int event:1'
bus.send(2); //'int event:2' 在这种情况下类型事件自动获取
/// 主题 = 'int^test'
bus.send<int>(3, eventName: 'test');//'int@test event:3'
//----- 使用EventDTO
bus
.listenEventDTO<int>()!
.listen((event) => print('topic ${event.topic} uuid:${event.uuid} event:${event.data}'));
bus
.listenEventDTO<int>(eventName: 'test')!
.listen((event) => print('topic ${event.topic} uuid:${event.uuid} event:${event.data}'));
当你调用listenEvent
方法时,你可以设置标志repeatLastEvent
,它会在等待1毫秒或指定的持续时间后发送事件。
V1 使用前缀和EventBusMaster
EventBusMaster是一个单例,它知道所有创建的EventBus并使用前缀进行排序。EventBusMaster还提供了从不同业务发送和接收事件的能力,如果没有EventBus,它将返回null或false。如果你使用任何EventBus通过前缀发送事件,且EventBus的前缀与指定的前缀不匹配,事件将被发送到EventBusMaster。
EventBus bus = EventBus();
EventBus busServices = EventBus(prefix: 'services');
/// 获取来自bus的事件
EventBusMaster.instance.listenEvent<int>()!.listen((event) => print('int master event:$event'));
/// 获取来自busServices的事件
EventBusMaster.instance
.listenEvent<int>(prefix: 'services')!
.listen((event) => print('int master services bus event:$event'));
bus.send<int>(5);
EventBusMaster.instance.send(6);
EventBusMaster.instance.send(7, prefix: 'services');
前缀可以用来将应用程序分为不同的层次,例如:
- ViewModel:用于存储模型的最新状态,不会删除未使用的节点。
- App:包含业务逻辑的层。
- AppModel:类似于ViewModel,用于存储应用运行所需的数据模型。
- Services和ServicesModel:分别对应服务层和数据模型层。
V1 EventBus for Model
默认情况下,EventBus在没有事件监听器的情况下不会清除事件节点。但是,如果你在构造函数中添加了标志isBusForModel
,你会得到一个不会清除事件节点的EventBus(EventModelController)。这个EventModelController可以用于持有资源管理器并更新对象(模型、提供者、命令、接口等)。
V1 EventBus Handler
EventBusHandlersGroup这个接口用于处理组。你可以将EventBusHandlersGroup连接到你的EventBus。
/// 事件处理器
typedef EventHandler<T> = Future<void> Function(
EventDTO<T> event,
/// 发送事件给其他监听器
EventEmitter<EventDTO<T>>? emit,
{EventBus? bus,
Completer<dynamic>? needComplete});
class TestHandlers implements EventBusHandlersGroup {
EventBusHandler? _bus;
@override
// TODO: 实现 isConnected
bool get isConnected => _bus != null;
@override
void connect(EventBusHandler bus) {
_bus = bus;
bus.addHandler<int>(plusNoEmit, eventName: 'no_emit');
bus.addHandler<int>(plusEmit, eventName: 'emit');
}
@override
void disconnect(EventBusHandler bus) {
// TODO: 实现 disconnect
}
Future<void> plusNoEmit(EventDTO<int> event, EventEmitter<EventDTO<int>>? emit,
{EventBus? bus, Completer? needComplete}) async {
print('plusNoEmit: ${event.data + 1}');
}
Future<void> plusEmit(EventDTO<int> event, EventEmitter<EventDTO<int>>? emit,
{EventBus? bus, Completer? needComplete}) async {
var e = event.copy(data: event.data + 1);
print('plusEmit: ${e.data}');
emit?.call(e);
}
}
Future<void> main() async {
EventBus bus = EventBus(prefix: 'test');
var handlers = TestHandlers();
handlers.connect(bus);
bus.send<void>(null, eventName: 'getMasterData'); // 调用 getMasterData 函数
bus.send(Test()); // 调用 test 函数
}
V1 方法:Call
如果事件有处理程序,处理程序可以处理needCompleter
并完成它。完成的结果将从未来返回。如果没有处理程序或者处理程序不支持needCompleter
,未来将完成一个错误。
try {
var r = await bus1.call('Hello');
} catch (e) {
print(e);
}
更多关于Flutter事件总线插件event_bus_arch的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter事件总线插件event_bus_arch的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用event_bus_arch
插件来实现事件总线的示例代码。event_bus_arch
是一个用于事件传递和状态管理的插件,它允许在不同的组件之间传递消息,而不需要直接引用对方。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加event_bus_arch
依赖:
dependencies:
flutter:
sdk: flutter
event_bus_arch: ^x.y.z # 替换为最新版本号
然后运行flutter pub get
来安装依赖。
2. 定义事件
创建一个新的事件类,比如MessageEvent
,它应该继承自Event
类:
// events/message_event.dart
import 'package:event_bus_arch/event_bus_arch.dart';
class MessageEvent extends Event {
final String message;
MessageEvent(this.message);
}
3. 注册事件总线
在你的应用入口(通常是main.dart
)中注册事件总线:
// main.dart
import 'package:flutter/material.dart';
import 'package:event_bus_arch/event_bus_arch.dart';
import 'events/message_event.dart';
void main() {
EventBusProvider.init(eventBus: EventBus());
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('EventBus Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
EventBusListenerWidget(),
EventBusEmitterWidget(),
],
),
),
),
);
}
}
4. 监听事件
创建一个监听事件的组件:
// widgets/event_bus_listener_widget.dart
import 'package:flutter/material.dart';
import 'package:event_bus_arch/event_bus_arch.dart';
import 'events/message_event.dart';
class EventBusListenerWidget extends StatefulWidget {
@override
_EventBusListenerWidgetState createState() => _EventBusListenerWidgetState();
}
class _EventBusListenerWidgetState extends State<EventBusListenerWidget> {
String message = '';
@override
void initState() {
super.initState();
EventBusProvider.getEventBus().on<MessageEvent>().listen((event) {
setState(() {
message = event.message;
});
});
}
@override
Widget build(BuildContext context) {
return Text('Received Message: $message');
}
}
5. 发射事件
创建一个可以发射事件的组件:
// widgets/event_bus_emitter_widget.dart
import 'package:flutter/material.dart';
import 'package:event_bus_arch/event_bus_arch.dart';
import 'events/message_event.dart';
class EventBusEmitterWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
EventBusProvider.getEventBus().emit(MessageEvent('Hello, EventBus!'));
},
child: Text('Emit Message'),
);
}
}
6. 运行应用
现在,你可以运行你的Flutter应用。当你点击“Emit Message”按钮时,EventBusListenerWidget
将接收到MessageEvent
事件并更新显示的文本。
总结
通过以上步骤,你已经成功地在Flutter项目中使用了event_bus_arch
插件来实现事件总线。这允许你在不同的组件之间传递消息,从而实现松耦合的通信。