我正在使用CakePHP 1.3,并尝试使用ajax制作一个简单的留言板。我正在尝试使用 Js 帮助程序在索引页上提交表单,然后刷新留言板的 div 以包含新消息。这一切都在一个页面上。
我之前曾就此发表过文章,但我想重新表述这个问题并包含一些更新。上一个问题可以看这里CakePHP中如何使用Js->submit()?
几天后我回到这个项目时,我立即进行了测试,并且该表单(在某种程度上)有效。提交表单会向数据库添加一条消息(它没有显示该消息,但我还没有攻击该部分)。它工作了 2 次,添加了 2 条消息。然后我打开控制器文件并注释掉一些调试代码,它停止工作。看来该操作未被调用。
这是我的 messages_controller.php:
<?php
class MessagesController extends AppController {
function index() {
$messages = $this->Message->find('all');
$this->set('messages',$messages);
}
function add() {
$this->autoRender = false;
$this->Session->setFlash('Add action called');
if($this->RequestHandler->isAjax()) {
$this->Session->setFlash('Ajax request made');
$this->layout = 'ajax';
if(!empty($this->data)) {
if($this->Message->save($this->data)) {
$this->Session->setFlash('Your Message has been posted');
}
}
}
}
}
?>
这是我的消息类的index.ctp
<div id="guestbook" class="section_box">
<h3 id="toggle_guestbook"><div class="toggle_arrow"></div>Sign our Guestbook</h3>
<?php
echo $this->Form->create('Message');
echo $this->Form->input('name', array('label' => 'From:'));
echo $this->Form->input('text', array('label' => 'Message:'));
echo $this->Js->submit('Post Your Message', array(
'url' => array(
'controller' => 'messages',
'action' => 'add'
),
'update' => '#message_board'
));
echo $this->Form->end();
echo $this->Js->writeBuffer(array('inline' => 'true'));
?>
<div id="message_board">
<?php foreach($messages as $message) { ?>
<div class="message">
<p class="message_txt">
<?php echo $message['Message']['text']; ?>
</p>
<div>
<div class="message_name">
<?php echo $message['Message']['name']; ?>
</div>
<div class="message_date">
<small>
<?php echo $message['Message']['date']; ?>
</small>
</div>
</div>
</div>
<?php } ?>
</div>
</div>
单击提交按钮后,我可以在控制台中看到使用正确的数据向 http://localhost/messages/add 发送了 POST。但似乎没有任何回应。闪现消息“调用添加操作”不是从控制器(或任何闪现消息,就此而言)设置的,并且 #message_board 的内容被清空。
如果我此时刷新页面,则会出现第二条闪现消息(“已发出 Ajax 请求”),并且 #message_board 的内容将被恢复。然而新消息没有保存,与之前的 2 条消息相同。
我被难住了。我有一种感觉,也许有更大的问题导致了我的问题,但我看不到它。任何帮助将不胜感激。
但是好像没有 回应...以及 #message_board 的内容是 清空了。
那是因为你还没有设置要渲染的动作/视图。您必须手动执行此操作,因为您已将
$this->autoRender
设置为 false
。您可以使用 render()
来执行此操作。更多信息可以在其各自的食谱页面找到。
如果您将
$this->autoRender
设置为 true
,那么它会将 #message_board 的内容替换为 add.ctp
的内容
闪烁消息“添加已调用的操作” 未从控制器(或任何 就此而言,闪现消息)
我认为您必须刷新页面或包含
$this->Session->flash()
位的部分才能显示 Flash 消息。
刷新页面时出现闪现消息意味着它确实调用并运行了该操作。
AFAIK,您只能在
Messages
数组中从 flash 键放置/打印一条消息。 flash 键是默认存储 flash 消息的位置。每次调用 setFlash()
都会覆盖旧调用设置的 Flash 消息。
由于只显示了第二条闪现消息,我们可以说它在第二次调用控制器中的
setFlash()
之后未能传递至少一个条件。您可能希望将 debug($this->data)
语句放在与 $this->data
相关的条件附近,以帮助自己调试问题。
您还可以使用
debug()
来了解您的应用程序是否经历了某个操作或路径,因为它几乎总是会显示。
因此您可以执行以下操作来检查它是否通过此条件:
if(!empty($this->data)) {
debug('Passed!');
如果“通过!”提交表格后会打印出来,我们就知道它通过了这个条件。
但是新消息没有保存
可能是因为 $data 为空或者验证失败。如果您的
$data
不为空,则可能验证失败,因为您的表单不会显示验证错误;你可能从来没有注意到它们。了解其是否通过验证的一种方法是执行以下操作:
$this->Message->set($this->data);
if ($this->Message->validates()) {
debug('it validated logic');
} else {
debug('didn't validate logic');
}
拉蒙的解决方案对我有用。这是更新后的代码。
控制器添加功能
function add() {
$this->autoRender = false;
if($this->RequestHandler->isAjax()) {
$this->layout = 'ajax';
if(!empty($this->data)) {
if ($this->Message->validates()) {
if($this->Message->save($this->data)) {
$this->render('/elements/message_board');
} else {
debug('didn\'t validate logic');
}
}
}
}
}
这是添加表单视图:
<?php
echo $this->Form->create('Message');
echo $this->Form->input('name', array('label' => 'From:'));
echo $this->Form->input('text', array('label' => 'Message:'));
echo $this->Js->submit('Post Your Message', array(
'url' => array(
'controller' => 'messages',
'action' => 'add'
),
'update' => '#message_board'
));
echo $this->Form->end();
echo $this->Js->writeBuffer(array('inline' => 'true'));
?>
<?php pr($this->validationErrors); ?>
<div id="message_board">
<?php echo $this->element('message_board'); ?>
</div>
我尝试使用与您使用的相同的解决方案,但它不起作用。当我直接在 URL 中访问它时,Ajax 没问题,而且我的印象是点击没有执行任何操作。当我使用
<fieldset><legend><?php __(' Run 1');?></legend>
<div id="formUpdateID"><div id="#error-message"></div>
<?php
$orders=array_merge($emptyarray,$orders['r1']['Order']);
echo $this->Form->create('Order');
echo $this->Form->input('id', array('value'=>$orders['id'],'type' =>'hidden'));
echo $this->Form->input('race_id', array('value'=> $orders['race_id'],'type' =>'hidden'));
echo $this->Form->input('driver_id', array('value'=>$session->read('Auth.User.driver_id'),'type' =>'hidden'));
echo $this->Form->input('run', array('value'=>$run,'type' =>'hidden'));
echo $this->Form->input('pm', array('value'=>$orders['pm'],'error'=>$err[$run]));
echo $this->Form->input('pr', array('value'=>$orders['pr'],'error'=>$err[$run]));
echo $this->Form->input('fuel', array('value'=>$orders['fuel'],'error'=>$err[$run]));
echo $this->Form->input('pit', array('value'=>$orders['pit'],'label' => __('Pit on lap '),'error'=>$err[$run]));
echo $this->Form->input('tyre_type', array('value'=>$orders['tyre_type'],'error'=>$err[$run]));
echo $this->Js->submit('Modify', array(
'url' => array(
'controller' => 'orders',
'action' => 'ajax_edit'
),
'update' => '#error_message'
));
echo $this->Form->end();
?>
<?php pr($this->validationErrors); ?>
</div></fieldset>
在视图和控制器“订单”中:
function ajax_edit($id=null){
$this->autoRender = false;
if($this->RequestHandler->isAjax()) {
die(debug('In Ajax'));
$this->layout = 'ajax';
debug('didn\'t validate logic');
}
echo 'hi';
}
不显示任何消息。
我之前有一些硬编码的 JS/ajax 不针对此代码部分。 我确实在 webroot/view 文件夹中复制了 ajax 布局。
我可以看到格式化源代码中显示的AJAX代码
<div class="submit"><input id="submit-1697561504" type="submit" value="Modify" /></div> </form><script type="text/javascript">
//<![CDATA[
$(document).ready(function () {$("#submit-1697561504").bind("click", function (event) {$.ajax({data:$("#submit-1697561504").closest("form").serialize(), dataType:"html", success:function (data, textStatus) {$("#error_message").html(data);}, type:"post", url:"\/Webmastering\/form1C\/frame\/orders\/ajax_edit\/1"});
return false;});});
//]]>
</script>
顺便说一句,我开始对 cakephp 中缺乏文档及其无法实现比在博客中发布帖子更复杂的任务感到厌倦。所以,在我开始破坏我的计算机之前,感谢您的帮助;)
我知道这是一个老话题,但我在我的应用程序中偶然发现了同样的问题,所以现在我认为 Thrax 做错了什么,即他没有放置
echo $this->Js->writeBuffer(array(' inline' => 'true'));在视图(或布局)文件中,就像 Logic Artist 所做的那样,因此不会生成用于处理提交按钮单击的脚本。