我有一个用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
,它将设置flash消息,重新加载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)
的地方,我可以访问响应数据并确定结果,然后添加flash消息,例如
if (response.success !== '') {
$('#outcome').html(response.success).addClass('alert alert-success');
}
哪个会将响应消息写入ID为#outcome
的div,并为样式目的添加适当的类。
当然有一种比这更好的方法,因为它会涉及重写我需要做的每一种方法吗?
为什么不执行控制器函数,然后用jquery工作重新加载页面,记住它在以这种方式处理时仍然可以访问$_SESSION
?
我看过插件,但想知道是否有一种原生的Cake方式来做这个我忽略的? Flash组件文档中未提及Ajax。
好的,我在评论中得到了@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
,然后有代码来呈现flash消息。
如果你重构代码以这种方式做事,你需要确保在这个例子中等效于foo()
的动作只是设置flash消息而不输出任何内容。您可以使用$this->autoRender = false
实现此目的,然后正常使用$this->Flash->set()
来设置您的消息。