【问题标题】:Yii: attaching events to modelsYii:将事件附加到模型
【发布时间】:2012-09-25 10:20:01
【问题描述】:

我有一个用户模型,它捆绑在我的 Yii 应用程序上安装的模块中。这个模块是第三方的,我不想修改它的代码。

我还有一个 Cv 模型,它与 User 模型具有 BELONGS_TO 关系。

我的问题是:删除用户后如何删除简历? 我知道我可以在 mysql 上使用on delete cascade ... 来实现这一点。但是,我确实需要删除其他数据,例如照片、文件等。

我的尝试

我创建了一个预加载在我的应用程序中的组件。此组件附加到 onAfterDelete 事件

class EventListener extends CComponent 
{
    public function init() {

        Yii::import("application.modules.users.models.User");

        User::model()->attachEventHandler('onAfterDelete', array($this, 'deleteUser'));
    }


    public function deleteUser($event)
    {
        // stuff here ...
    }
}

但是这不起作用。

有什么建议吗?

【问题讨论】:

  • 查看 User 类中的任何 'on%' 方法以及它的父级,以了解该模型支持哪些事件。
  • 我通常创建新类 myUser 扩展 User 我写下我的 onAfterDelete
  • @Sergey 当一个用户模型被删除时,onAfterDelete 事件不会自动引发吗?

标签: yii yii-components yii-events


【解决方案1】:

这可能会对你有所帮助。

User::model() 是单例

$user1 = User::model();
$user2 = new User; // will be used in insert action
$user3 = User::model()->findByPk(10); // will be used in update/delete action

$user1、$user2 和 $user3 是完全不同的对象。 您可以将事件附加到对象,在这种情况下,您必须分别将事件添加到所有这 3 个对象。

$user1->attachEventHandler(...);
$user2->attachEventHandler(...);
$user3->attachEventHandler(...);

看起来 Yii 没有提供任何在类级别添加事件的方法。

【讨论】:

  • 好的,我得出了相同的结论,但是有没有办法在不改变基本用户模型的情况下将事件处理程序附加到每个创建的模型?
  • 但是,您可以在 User 模型类的 ->init() 方法上运行 attachEventHandler(),因此每个用户模型都会附加事件处理程序。
【解决方案2】:

好吧,伙计们,我刚刚偶然发现了同样的问题,我是这样解决的:

您应该使用模型的 init(),而不是事件侦听器集合类。

就我而言,我有 devModel 类:

    public function init()
{
    parent::init(); 
    $this->onLicenseUpdated = array(new MEventProcessor, 'licenseUpdateHandler');
}

并且处理程序是 MEventProcessor 类中的 licenseUpdateHandler($event)。

这样每次您使用模型实例时,它都会为每个对象调用 init() 并将事件处理程序附加到此模型的每个实例。

现在任何时候为模型调用事件(在我的例子中是 onLicenseUpdated()) - 处理程序也会被调用。

【讨论】:

    【解决方案3】:

    您也可以使用行为

    1 - 行为可以监听事件:你只需要覆盖他们的 events() 方法

    类 MyBehavior 扩展行为 {

    public function events() {
        return [
            ActiveRecord::EVENT_BEFORE_VALIDATE => 'beforeValidate',
        ];
    }
    
    public function beforeValidate($event) {
        // ...
    }
    

    }

    2 - 虽然在组件的 behavior() 方法中将行为附加到组件更为常见,但您也可以动态附加它们并保持原始代码不变:

    use app\components\MyBehavior;
    
     // attach a behavior object
    
     $component->attachBehavior('myBehavior1', new MyBehavior);
    

    你会在这里找到一些有用的文档:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-04
      相关资源
      最近更新 更多