事件系统
Events (事件)
简介
Masonent Events 是一个易于使用的集成,用于订阅事件。这些事件可以放置在整个应用程序中,并在发生各种操作时触发。例如,当用户注册时,您可能希望执行以下几个操作:
- 发送电子邮件
- 订阅 MailChimp
- 更新数据库的一部分
设置侦听器后,就可以在控制器中使用一行代码中执行所有这些操作
入门
安装
首先,我们需要使用 pip 安装软件包:
$ pip install masonite-events
服务提供者
安装完成后,我们需要将提供者添加到我们的提供者列表中:
config/providers.py
from events.providers import EventProvider
...
PROVIDERS = [
...
EventProvider,
...
]
命令
该服务提供者将添加新的 event:listener
命令,我们可以使用该命令来创建新事件。下面我们将逐步介绍如何在创建一个事件侦听器。
创建事件侦听器
Masonent Events 允许您使用各种事件侦听器订阅任意事件操作。在本文中,我们将介绍为订阅应用程序的新用户设置侦听器的步骤。
我们可以通过执行以下命令来创建事件侦听器:
$ craft event:listener SubscribeUser
这将在 app/events 目录中创建一个新事件,如下所示:
""" A SubscribeUser Event """
from events import Event
class SubscribeUser(Event):
""" SubscribeUser Event Class """
subscribe = []
def __init__(self):
""" Event Class Constructor """
pass
def handle(self):
""" Event Handle Method """
pass
关于侦听器类
这是一个非常简单的类。我们有由容器解析的 _init_
方法,还有同样由容器解析的 handle
方法。
这意味着我们可以使用如下语法:
from masonite.request import Request
...
def __init__(self, request: Request):
""" Event Class Constructor """
self.request = request
...
Subscribe 属性
Subscribe 属性可以用作速记,稍后我们将看到它,它应该是我们要订阅的事件列表:
""" A SubscribeUser Event """
from events import Event
from package.action import SomeAction
class SubscribeUser(Event):
""" SubscribeUser Event Class """
subscribe = ['user.subscribed', SomeAction]
def __init__(self):
""" Event Class Constructor """
pass
def handle(self):
""" Event Handle Method """
pass
订阅事件
我们只需将侦听器传递给您应用程序的其中一个服务提供者的 boot 方法,就可以简单地实现事件监听。此服务提供者最好应具有 wsgi=False
,这样您就不会在每个请求上都持续订阅同一侦听器了。
您可能已经有了一个 wsgi 属性为 false 的服务提供者,但我们还是创建一个新的:
$ craft provider ListenerProvider
确保我们将 wsgi 属性设置为 False:
''' A ListenerProvider Service Provider '''
from masonite.provider import ServiceProvider
class ListenerProvider(ServiceProvider):
wsgi = False
def register(self):
pass
def boot(self):
pass
现在我看可以导入我们的侦听器并将它添加到我们的 boot 方法中:
''' A ListenerProvider Service Provider '''
from masonite.provider import ServiceProvider
from app.events.SubscribeUser.SubscribeUser
from events import Event
class ListenerProvider(ServiceProvider):
wsgi = False
def register(self):
pass
def boot(self, event: Event):
event.subscribe(SubsribeUser)
与下面提供的更手动的方法相比,这是推荐的方法,但是如果您发现需要其中一个而不是另一个,则这两个选项都是可用的。
因为我们的侦听器上有一个 subscribe 属性,所以我们可以简单地将操作传递到 subscribe 方法中。这将为我们的侦听器订阅 SomeAction
和 user.subscribed
操作,这些操作是我们在侦听器类的subscribe
属性中指定的。
手动侦听事件
如果我们没有在 subscribe 属性中指定操作,我们可以在服务提供者的 boot 方法中使用 listen 方法手动订阅它们:
''' A ListenerProvider Service Provider '''
from masonite.provider import ServiceProvider
from app.events.SubscribeUser.SubscribeUser
from events import Event
class ListenerProvider(ServiceProvider):
wsgi = False
def register(self):
pass
def boot(self, event: Event):
event.listen('user.subscribed', [SubsribeUser])
确保 listen 方法中的第二个参数是 list;即使它只有一个值
触发事件
现在我们有了被监听的事件,我们可以开始触发事件了。触发事件有两种方法。在应用程序的任何部分,我们都可以做到这两点,不过我们将介绍如何在控制器方法中做到这一点。
Fire 方法
from events import Event
...
def show(self, event: Event):
event.fire('user.subscribed')
Event 辅助方法
Masonite Events 还附带了一个新的内置辅助方法:
def show(self):
event('user.subscribed')
这两种方法都将触发我们所有正在监听 user.subscribed
事件操作的侦听器。
Class Events
如上文所述,我们可以将类订阅为事件:
from package.action import SomeAction
def show(self):
event(SomeAction)
这将经历与上面使用字符串订阅的事件相同的步骤。
通配符事件
我们还可以使用 * 通配符操作触发事件:
def show(self):
event('user.*')
这将触发诸如 user.subscribed
,user.created
,user.deleted
之类的事件。
我们还可以触发前面带有星号的事件:
def show(self):
event('*.created')
这将触发诸如 user.created
, dashboard.created
和 manager.created
之类的事件。
我们还可以触发中间带有通配符的事件:
def show(self):
event('user.*.created')
这将触发诸如 user.manager.created
, user.employee.created
和 user.friend.created
之类的事件。
传递参数
有时,您可能希望将控制器 (或无论您在何处调用代码) 的参数传递给事件的 handle
方法。在这种情况下,您可以像这样简单地将关键字参数传递给您的 fire
方法:
def show(self, event: Event):
event.fire('user.subscribed', to='user@email.com', active='True')
并且可以使用 argument
方法在 handle
方法中获取这些值:
class SubscribeUser(Event):
""" SubscribeUser Event Class """
subscribe = ['user.subscribed', SomeAction]
def __init__(self):
""" Event Class Constructor """
pass
def handle(self):
""" Event Handle Method """
self.argument('to') # user@email.com
self.argument('active') # True
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。