Yii2 中的事件是如何工作的

How events work in Yii2

我一直在尝试从 Yii Guide 学习 Yii 中事件的工作原理。我发现有最重要的东西:Event HandlersAttaching Event HandlersTriggering Events。我已经正确阅读了整篇文章。但我不明白如何正确实施这三件事。如何查看它的实施效果。我已将 component class 扩展为:

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);
   }

}

我不明白接下来要做什么。我应该在哪里写 Attaching Event Handlers。你能帮帮我吗,至少我可以看到一个简单的输出使用事件。

您可以在模型中创建 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']);
    }

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

[$this, 'sendInLog']

sendInLog是模型中的方法。在方法 sendInLog 中,一个参数是 $event。这是对象 \yii\base\Event。在 属性 $event->name 中 - 它是事件名称。在 属性 $event->sender - 它是来自触发事件的模型 class。

在我的 class 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();
    }
}

运行 像那样触发:

public function afterDelete()
    {
        $this->trigger(Event::ACTION_DELETE);
        parent::afterDelete();
    }

public function actionView()
    {
        $this->trigger(Event::ACTION_VIEW);
        $this->render(...);
    }

编辑:

例如。如果你想在删除、插入、更新后触发运行。您可以在模型中的 afterDeleteafterSave 中使用触发器。如果你想 运行 在控制器中触发 运行 触发这样的:

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
            ]);
        }
    }

我向您展示了两种不同的 运行 触发方式。使用哪一个由您决定:)