2013-04-09 29 views
2

我想从模型beforeSave()方法发送特定消息。 Flash消息不起作用。我可以从控制器发送这个消息并使用一些参数,但我不认为这是最好的解决方案。使用print也不好。CakePHP如何设置来自Model的消息?

所以我的问题是如何发送任何消息到控制器/视图从模型?

+0

为什么你要发送的消息。你能更具体地说明你在做什么吗?也许也发布一些代码?通常是相反的。控制器将使用模型并调用方法并返回一些内容以继续。 – mark 2013-04-09 15:53:05

+0

+1。如果你需要从模型到控制器'传达'一个消息(即超过*'失败'*),抛出一个'Exception'可能是一个选择。阅读本章文档[例外](http://book.cakephp.org/2.0/en/development/exceptions.html) – thaJeztah 2013-04-09 17:29:43

+0

例外的想法很好。返回消息应该是关于传递给模型的数据,所以我将通过这次验证来完成。但是我关心的是,当我需要返回由'afterSave()'回调中的某些处理引起的消息或者验证无效的地方时,我应该怎么做。 'Exception'很好,但它强制使用控制器中的try/catch或自定义错误处理。我在想如何挂钩模型中的** flash消息**。 – 2013-04-10 12:24:59

回答

8

试试这个

在你的模型:

public function beforeSave($options = array()){ 
    if($not_ok){ 
     $this->error = __('My error message'); 
     return false; 
    } 
    return true; 
} 

在你的控制器:

public function add(){ 
    $save = $this->Modelname->save($this->request->data); 
    if(!save){ 
     $this->Session->setFlash($this->Modelname->error); 
     $this->redirect($this->referer()); 
    } 
} 
1

那么Session-> setFlash()显然不起作用,因为它是Session组件的一部分,但是 会话组件使用静态单例类CakeSession,它有方法CakeSession :: write()所有你需要做的是传递数组写入方法,该方法的结构与Session :: setFlash()将生成的结构相同,因此,当您在视图中使用Session :: flash()时,将从控制器的setFlash()获得相同的结果。

做参考:http://api.cakephp.org/2.2/class-CakeSession.html从评论

片段,被放置在模型的方法。

App::uses('CakeSession','Model/Datasource');    
      CakeSession::write('Message', array(
       'flash' => array(
        'message' => 'your message here', 
        'element' => 'default', 
        'params' => null, 
       ), 
      )); 
+0

好主意,但我不知道如何使用它。无法从'setFlash()'中找到结构,因此它对我无用。在CakePHP 2.x中没有'Session'类。有'SessionComponent'和'SessionHelper'。也许别人会知道如何使用它。我会通过验证返回消息。 – 2013-04-10 12:19:08

+0

这是一个snipett我放在我的模型,以检查它是否也工作,我也创建了一个setFlash()结构。它在蛋糕2.x上,检查它是否适合你。 'App :: uses('CakeSession','Model/Datasource'); CakeSession :: write('Message',array( 'flash'=> array( 'message'=>'Your message here', 'element'=>'default', 'params'=> null, ), ));' 我还不确定你的模型是否应该负责这部分逻辑。 更新了答案。 – johhniedoe 2013-04-10 14:46:35

+1

国际海事组织直接从模型访问这个会话是*不可*。例如,考虑在Shell(命令行/ cron作业)中使用相同模型的情况。在这种情况下,将不会有Session,因此无法输出该消息。例外或其他机制是更好的解决方案。在Controller(或Shell)中检索该消息并按照它应该的方式输出它;在控制器中使用'Session-> setFlash()'或将它写入“日志”或发送一封电子邮件,以防它是一个Shell任务 – thaJeztah 2013-04-11 22:50:49

1

通过执行以下操作,你就可以在你的模型中设定闪烁任何一点,而不必担心在控制器中再次声明它们,因为它们会自动设置在呈现页面之前,在您的应用程序控制器中。

在AppController中:

public function beforeRender() { 
    parent::beforeRender(); 
    $this->generateFlashes(); 
} 

public function generateFlashes() { 
    $flashTypes = array('alert', 'error', 'info', 'success', 'warning'); 
    $model = $this->modelClass; 

    foreach($flashTypes as $type) { 
    if(!empty($this->$model->$type)) { 
     $message = '<strong>' . ucfirst($type) . ':</strong> ' . $this->$model->$type; 
     $this->Flash->error($message, array('escape' => false)); 
    } 
    } 
} 

在型号:

public function beforeSave($options = array()){ 
    if($not_ok){ 
    $this->error = __('My error message'); 
    return false; 
    } 
    return true; 
} 

在控制器:

public function add(){ 
    // $this->modelClass will use whatever the actual model class is for this 
    // controller without having to type it out or replace the word modelClass 
    $save = $this->{$this->modelClass}->save($this->request->data); 
    if(!save){ 
    // no need to set flash because it will get created in AppController beforeRender() 
    $this->redirect($this->referer()); 
    } 
}