Advanced

事件

简介

当您需要在应用中某些事情发生后处理逻辑时,事件非常强大。Nylo 的事件系统允许您从应用的任何地方创建、派发和监听事件,使构建响应式、事件驱动的 Flutter 应用更加容易。

理解事件

事件驱动编程是一种编程范式,其中应用的流程由事件决定,例如用户操作、传感器输出或来自其他程序或线程的消息。这种方式有助于解耦应用的不同部分,使代码更易于维护和理解。

常见事件示例

以下是您的应用可能使用的一些典型事件:

  • 用户注册完成
  • 用户登录/退出
  • 商品添加到购物车
  • 支付处理成功
  • 数据同步完成
  • 收到推送通知

创建事件

您可以使用 Nylo 框架 CLI 或 Metro 创建新事件:

metro make:event PaymentSuccessfulEvent

运行命令后,将在 app/events/ 目录中创建一个新的事件文件。

事件结构

以下是新创建的事件文件结构(例如 app/events/payment_successful_event.dart):

import 'package:nylo_framework/nylo_framework.dart';

class PaymentSuccessfulEvent implements NyEvent {
  final listeners = {
    DefaultListener: DefaultListener(),
  };
}

class DefaultListener extends NyListener {
  handle(dynamic event) async {
    // Handle the payload from event
  }
}

派发事件

可以使用 event 辅助方法从应用的任何位置派发事件。

基本事件派发

不带数据派发事件:

event<PaymentSuccessfulEvent>();

带数据派发

与事件一起传递数据:

event<PaymentSuccessfulEvent>(data: {
  'user': user,
  'amount': amount,
  'transactionId': 'txn_123456'
});

广播事件

默认情况下,Nylo 事件仅由事件类中定义的监听器处理。要广播事件(使其对外部监听器可用),请使用 broadcast 参数:

event<PaymentSuccessfulEvent>(
  data: {'user': user, 'amount': amount},
  broadcast: true
);

监听事件

Nylo 提供了多种监听和响应事件的方式。

使用 listenOn 辅助函数

listenOn 辅助函数可以在应用的任何位置使用,用于监听广播的事件:

NyEventSubscription subscription = listenOn<PaymentSuccessfulEvent>((data) {
  // Access event data
  final user = data['user'];
  final amount = data['amount'];

  // Handle the event
  showSuccessMessage("Payment of $amount received");
});

使用 listen 辅助函数

listen 辅助函数可在 NyPageNyState 类中使用。它自动管理订阅,在组件被销毁时取消订阅:

class _CheckoutPageState extends NyPage<CheckoutPage> {
  @override
  get init => () {
    listen<PaymentSuccessfulEvent>((data) {
      // Handle payment success
      routeTo(OrderConfirmationPage.path);
    });

    listen<PaymentFailedEvent>((data) {
      // Handle payment failure
      displayErrorMessage(data['error']);
    });
  };

  // Rest of your page implementation
}

取消订阅事件

使用 listenOn 时,您必须手动取消订阅以防止内存泄漏:

// Store the subscription
final subscription = listenOn<PaymentSuccessfulEvent>((data) {
  // Handle event
});

// Later, when no longer needed
subscription.cancel();

listen 辅助函数在组件被销毁时会自动处理取消订阅。

使用监听器

监听器是响应事件的类。每个事件可以有多个监听器来处理事件的不同方面。

添加多个监听器

您可以通过更新 listeners 属性向事件添加多个监听器:

class PaymentSuccessfulEvent implements NyEvent {
  final listeners = {
    NotificationListener: NotificationListener(),
    AnalyticsListener: AnalyticsListener(),
    OrderProcessingListener: OrderProcessingListener(),
  };
}

实现监听器逻辑

每个监听器应实现 handle 方法来处理事件:

class NotificationListener extends NyListener {
  handle(dynamic event) async {
    // Send notification to user
    final user = event['user'];
    await NotificationService.sendNotification(
      userId: user.id,
      title: "Payment Successful",
      body: "Your payment of ${event['amount']} was processed successfully."
    );
  }
}

class AnalyticsListener extends NyListener {
  handle(dynamic event) async {
    // Log analytics event
    await AnalyticsService.logEvent(
      "payment_successful",
      parameters: {
        'amount': event['amount'],
        'userId': event['user'].id,
      }
    );
  }
}

全局事件广播

如果您希望所有事件自动广播,而无需每次指定 broadcast: true,可以启用全局广播。

启用全局广播

编辑您的 app/providers/app_provider.dart 文件,并在 Nylo 实例上添加 broadcastEvents() 方法:

class AppProvider implements NyProvider {
  @override
  boot(Nylo nylo) async {
    // Other configuration

    // Enable broadcasting for all events
    nylo.broadcastEvents();
  }
}

启用全局广播后,您可以更简洁地派发和监听事件:

// Dispatch event (no need for broadcast: true)
event<PaymentSuccessfulEvent>(data: {
  'user': user,
  'amount': amount,
});

// Listen for the event anywhere
listen<PaymentSuccessfulEvent>((data) {
  // Handle event data
});