CakePHP 3.x用于ajax请求的Flash消息

时间:2018-09-04 13:36:02

标签: jquery ajax cakephp

我有一个用CakePHP 3.5.13编写的应用程序

它利用Cake内置的Flash Component。以标准方式(例如

)进行配置时,所有这些都可以正常工作
// src/Controller/SomeController.php
public function foo()
{ 
    $this->Flash->set('Records updated', ['element' => 'success']);
    return $this->redirect(['action' => 'index']);
}

// src/Template/SomeController/index.ctp
<?= $this->Flash->render() ?>

因此,如果我访问/some-controller/foo,它将设置即显消息,重新加载index.ctp并显示它。

但是,我想修改内容,使其全部通过ajax调用完成。

如果我创建一个新模板,/src/Template/SomeController/index.ctp并使用以下jquery:

$('.foo-test').click(function(e) {
    e.preventDefault();

    $.ajax({
        url: '/some-controller/foo'
    }).done(response) {
       //console.log(response);
       window.location.href = '/some-controller/index'; 
    });
});

当我单击类为.foo-test的锚点时,它将发出ajax请求。

但是重新加载页面(window.location.reload)不会显示Flash消息。为什么会这样,因为这等效于浏览器重新加载/some-controller/index,对吗?

我想修改此方法的唯一方法是让foo()返回JSON响应。然后,在我使用过console.log(response)的地方,我可以访问响应数据并确定结果,然后添加即显消息,例如

 if (response.success !== '') {
     $('#outcome').html(response.success).addClass('alert alert-success');
 }

将响应消息写入ID为#outcome的div并添加适当的类以进行样式设置。

当然有比这更好的方法了,因为这将涉及重写我需要执行的每个方法?

为什么不执行控制器功能,然后用jquery工作重新加载页面,同时牢记以这种方式执行操作时仍可以访问$_SESSION

我看过插件,但是想知道我是否忽略了本地的Cake方法? Flash组件文档中未提及Ajax。

1 个答案:

答案 0 :(得分:0)

好吧,我已经在@ndm的评论中找到了答案。

解决方案是删除SomeController::foo()中的PHP重定向:

public function foo()
{ 
    // There is no template (foo.ctp) associated with this function.
    $this->autoRender = false;

    $this->Flash->set('Records updated', ['element' => 'success']);

    // Remove line below:
    //return $this->redirect(['action' => 'index']);
}

这是因为我们在jquery中进行了等效的重定向:

window.location.href = '/some-controller/index'; 

因此,对/some-controller/foo的ajax请求仍然设置了Flash消息。使用jquery重定向可重新加载index.ctp,该foo()然后具有呈现Flash消息的代码。

如果要重构代码以这种方式执行操作,则需要确保在此示例中,等效于$this->autoRender = false的操作仅设置了闪现消息,并且不输出任何内容。您可以使用$this->Flash->set()实现此目的,然后照常使用{{1}}来设置您的消息。