我有一个用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。
答案 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}}来设置您的消息。