事件如何在Yii2中发挥作用

Str*_*der 2 php yii yii2

我一直试图从Yii指南中了解事件在Yii中的运作方式.我发现有最重要的事情:Event Handlers,Attaching Event HandlersTriggering Events.我已经正确阅读了整篇文章.但我不明白如何正确实施这三件事.如何看待它的实施效果.我把component课程扩展为:

namespace app\components;

use yii\base\Component;
use yii\base\Event;
use yii\web\View;

class Foo extends Component{

   const EVENT_HELLO = 'hello';

   public function bar()
   {
      $this->trigger(self::EVENT_HELLO);
   }

}
Run Code Online (Sandbox Code Playgroud)

我不明白下一步要做什么.我应该在哪里编写附加事件处理程序.你能帮助我一个人,至少我可以看到一个简单的输出事件.

vit*_*_74 11

您可以init()在模型中创建方法:

public function init()
    {
        $this->on(Event::ACTION_ADD, ['app\models\Event', 'sendInLog']);
        $this->on(Event::ACTION_DELETE, ['app\models\Event', 'sendInLog']);
        $this->on(Event::ACTION_UPDATE, ['app\models\Event', 'sendInLog']);
    }
Run Code Online (Sandbox Code Playgroud)

在初始化第二个参数中的事件时,您可以使用当前模型或设置其他模型.如果你想使用这样的当前模型集:

[$this, 'sendInLog']
Run Code Online (Sandbox Code Playgroud)

sendInLog它是模型中的方法.在方法sendInLog一参数中$event.这是对象\yii\base\Event.在财产$event->name- 它是事件名称.在属性中$event->sender- 它是触发事件的模型类.

在我的课堂app\models\Event上:

namespace app\models;

class Event extends Component
{
    const ACTION_ADD = 1;
    const ACTION_DELETE = 2;
    const ACTION_UPDATE = 3;

    const TYPE_PROJECT = 10;
    const TYPE_BIDS = 20;
    const TYPE_BIDS_DATA = 30;

    /**
     * @param $event
     */
    public static function sendInLog($event)
    {
        /** @var \yii\base\Event $event */
        /** @var ActiveRecord $event->sender */
        $userId = Yii::$app->user->id;
        $model = new Logs([
            'type' => $event->sender->getType(),
            'action' => $event->name,
            'id_user' => $userId,
            'old_data' => Json::encode($event->sender->attributes),
            'new_data' => Json::encode($event->sender->oldAttributes),
        ]);
        $model->save();
    }
}
Run Code Online (Sandbox Code Playgroud)

像这样运行触发器:

public function afterDelete()
    {
        $this->trigger(Event::ACTION_DELETE);
        parent::afterDelete();
    }
Run Code Online (Sandbox Code Playgroud)

要么

public function actionView()
    {
        $this->trigger(Event::ACTION_VIEW);
        $this->render(...);
    }
Run Code Online (Sandbox Code Playgroud)

编辑:

例如.如果要在删除后运行触发器,请插入,更新.您可以使用触发器afterDelete,afterSave在模型.如果你想在控制器运行触发器中运行触发器,那样:

public function actionCreate()
    {
        $model = new Bids();
        $model->id_project = Yii::$app->request->get('projectId');
        $fieldsDefaults = BidsFieldsDefaults::find()->orderBy(['order' => SORT_ASC])->all();

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            $model->trigger(Event::ACTION_ADD);
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('create', [
                'model' => $model,
                'fieldsDefaults' => $fieldsDefaults
            ]);
        }
    }
Run Code Online (Sandbox Code Playgroud)

我向您展示了两种不同的运行触发器的方法.哪一个使用取决于你:)