Flutter事件总线插件event_bus_arch的使用

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

Flutter事件总线插件event_bus_arch的使用

关于

这个包是事件驱动架构的一部分,提供发送、监听、处理和接收事件的功能。

V2 简单使用

EventBus在V2中有三个主要方法:sendlistenlastData

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

1 回复

更多关于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插件来实现事件总线。这允许你在不同的组件之间传递消息,从而实现松耦合的通信。

回到顶部