【问题标题】:Dispatching events from an extended class从扩展类调度事件
【发布时间】:2018-06-05 15:37:13
【问题描述】:

在 Laravel 5.5 项目中,我有一个 Person 类和一个 Student 类。 Student 类扩展了 Person 类。我有很多事情需要在创建一个新人时发生,还有很多事情需要在创建一个新学生(当然也是一个人)时发生。

我的课程看起来像这样......

class Person extends Model {
        protected $dispatchesEvents = [
            'created' => PersonJoins::class
        ];}

.

class Student extends Person {    
        protected $dispatchesEvents = [
            'created' => StudentIsCreated::class,
        ];}

创建新的 Student 实例时,会触发 StudentIsCreated 事件,但不会触发 PersonJoins 事件。

解决方法是将其中一个模型中的“已创建”更改为“已保存”,然后触发两个事件。由此看来,正在发生的事情似乎很明显。 Person 模型上 $dispatchesEvents 数组中的“created”元素被 Student 模型上的相同元素覆盖。即使只是输入,似乎解决方案应该很明显,但我看不到它。

所以,我的问题是……如何让两个模型上的“创建”事件触发,其中一个扩展另一个?

谢谢。 大卫。

编辑: 阅读@hdifen 答案后。我的学生模型现在看起来像这样......

class Student extends Person
{
  protected static function boot()
    {
        parent::boot();
        static::created(function($student) {
            \Event::Fire('StudentCreated', $student);
    });
}

}

App\Events\StudentCreated.php 我有...

class StudentCreated
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($student)
    {
        echo ("\r\nStudentCreated event has fired");
        $this->student = $student;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('Student-Is-Created-Channel');
    }
}

但该事件似乎没有被触发。我做错了吗?

【问题讨论】:

  • 您如何在数据库中区分这两种模型?
  • @GaimZz 数据库中没有 Person 表。 Person 类仅用于处理适用于所有类型用户(目前是学生和员工)的事情。计划是,当创建一个人时,无论是学生还是员工,PersonJoins 事件都会创建一个用户。创建学生时,以及因为 Student 扩展 Person 而创建的用户,我希望触发 StudentIsCreated 事件,该事件将创建一个新的 Grades 模型实例。
  • 根据 laravel 文档的解释,Laravel 事件仅绑定到 1 个模型,所以如果我是你,我要么重新考虑你的架构,要么使用“保存”事件解决方法

标签: php laravel events


【解决方案1】:

是的,你是正确的,学生模型正在覆盖父变量 $dispatchesEvents。

我建议不要使用$dispatchedEvent,因为事件主要用于如果您正在做一些更复杂的事情,需要您的代码的其他部分在它们被触发时做出反应。

简单的解决方案是手动挂钩到模型中的 created 事件,在您的情况下,您想在创建学生时创建成绩模型?

protected static function boot()
{
    parent::boot();
    static::created(function($model) {
        $grade = new Grade;
        $model->grades->save($grade);
        // Or if you really want to use an event something like
        Event::fire('student.created', $student);
    });
}

这篇文章可能会给你一个想法:

Laravel Model Events - I'm a bit confused about where they're meant to go.

【讨论】:

  • 感谢您的回答。你知道 Event:fire 在 Laravel 5.5 中是否仍然有效吗?它似乎没有为我触发事件。我仍然想使用事件,因为创建成绩模型只是一个例子。创建学生时会发生更多事情。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-14
  • 2018-02-22
  • 1970-01-01
  • 2022-11-13
相关资源
最近更新 更多