【问题标题】:Yii2: ActiveRecord events that only trigger on a scenarioYii2:仅在场景上触发的 ActiveRecord 事件
【发布时间】:2016-04-07 11:19:39
【问题描述】:

有没有人需要绑定 ActiveRecord 事件处理程序,使其仅在某些情况下触发?

在理想情况下,ActiveRecord on() 方法也将采用 $scenarios 参数,并且仅当 ActiveRecord 在事件发生时正在使用该场景时才触发处理程序。但由于情况并非如此,我正在寻找一种干净、可靠的方式来实现此类功能。

编辑:这需要与 any 事件一起使用,包括由 Yii 框架触发的内置事件(例如 ActiveRecord::EVENT_AFTER_INSERT)。

【问题讨论】:

  • 我认为您可以扩展 \yii\base\Event 并添加自己的方法 onScenario()。它将与on() 相同,但会在场景中增加一个参数。您可以像 ActiveRecord 中的方法 scenarios() 一样使用它。此外,您还需要覆盖 trigger() 方法并在父调用之前添加场景检查。

标签: events activerecord yii2 scenarios


【解决方案1】:

我第一条评论的改进。

class ScenarioEvent extends \yii\base\Event
{
    private static $_events = [];

    public static function onScenario($scenario, $class, $name, $handler, $data = null)
    {
        // You may use foreach if you wil use many scenarios for event
        if (!isset(self::$_scenarios)) {
            self::$_scenarios[$scenario] = [];
        }
        self::$_scenarios[$scenario][$name][] = $class;
        return static::on($class, $name, $handler, $data);
    }

    public static function trigger($class, $name, $event = null)
    {
        if (
            // If event is null assumed that it has no sender with scenario
            $event === null
            || empty(self::$_scenarios[$event->sender->scenario][$name])
        ) {
            parent::trigger($class, $name, $event);
        } else {
            $classes = array_merge(
                [$class],
                class_parents($class, true),
                class_implements($class, true)
            );

            foreach ($classes as $class) {
                if (in_array($class, self::$_scenarios[$event->sender->scenario][$name])) {
                    parent::trigger($class, $name, $event);
                    break;
                }
            }
        }
    }
}

【讨论】:

  • 遗憾的是,这可能仅适用于手动触发的事件(我不需要)。它不适用于任何自动触发的内置事件(例如\yii\db\ActiveRecord 中的\yii\db\AfterSaveEvent),这是我真正需要的。
猜你喜欢
  • 2014-05-07
  • 1970-01-01
  • 2012-10-24
  • 2016-12-26
  • 2013-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多