在本节中,我们将实现评论显示和创建功能。
为了增强用户互动性,我们希望在用户每次完成输入一个字段后提示其可能的错误。这被称为客户端输入验证。我们将展示如何在 Yii 中轻松无缝地完成此操作。请注意,这需要 Yii 版本 1.1.1 或更高版本。
我们不分别在各个页面上显示和创建评论,而是在帖子详情页面(由 PostController
的 view
操作生成)上进行操作。在帖子内容显示下方,我们首先显示属于该帖子的评论列表,然后显示一个评论创建表单。
为了在帖子详情页面上显示评论,我们修改视图脚本 /wwwroot/blog/protected/views/post/view.php
如下所示:
...post view here... <div id="comments"> if($model->commentCount>=1): <h3> echo $model->commentCount . 'comment(s)'; </h3> $this->renderPartial('_comments',array( 'post'=>$model, 'comments'=>$model->comments, )); endif; </div>
在上面,我们调用 renderPartial()
来渲染一个名为 _comments
的局部视图,以显示属于当前帖子的评论列表。请注意,在视图中,我们使用表达式 $model->comments
来检索帖子的评论。这是有效的,因为我们在 Post
类中声明了一个 comments
关系。评估此表达式将触发一个隐式 JOIN 数据库查询,以返回正确的评论。此功能称为 延迟关联查询。
局部视图 _comments
并不复杂。它主要遍历每个评论并显示其详细信息。感兴趣的读者可以参考 /wwwroot/yii/demos/blog/protected/views/post/_comments.php
。
为了处理评论创建,我们首先修改 PostController
的 actionView()
方法如下:
public function actionView()
{
$post=$this->loadModel();
$comment=$this->newComment($post);
$this->render('view',array(
'model'=>$post,
'comment'=>$comment,
));
}
protected function newComment($post)
{
$comment=new Comment;
if(isset($_POST['Comment']))
{
$comment->attributes=$_POST['Comment'];
if($post->addComment($comment))
{
if($comment->status==Comment::STATUS_PENDING)
Yii::app()->user->setFlash('commentSubmitted','Thank you for your comment. Your comment will be posted once it is approved.');
$this->refresh();
}
}
return $comment;
}
然后我们通过添加 addComment()
方法修改 Post
模型类如下:
public function addComment($comment)
{
if(Yii::app()->params['commentNeedApproval'])
$comment->status=Comment::STATUS_PENDING;
else
$comment->status=Comment::STATUS_APPROVED;
$comment->post_id=$this->id;
return $comment->save();
}
在上面,我们在渲染 view
之前调用 newComment()
方法。在 newComment()
方法中,我们生成一个 Comment
实例,并检查是否提交了评论表单。如果是,我们尝试通过调用 $post->addComment($comment)
为帖子添加评论。如果成功,我们将刷新帖子详情页面,这将显示新创建的评论(除非需要审批)。如果评论首先需要审批才能显示,我们将显示一条闪存消息,告知用户评论将在批准后显示。闪存消息通常是显示给最终用户的确认消息。如果用户单击其浏览器的刷新按钮,该消息将消失。
我们还需要进一步修改 /wwwroot/blog/protected/views/post/view.php
:
...... <div id="comments"> ...... <h3>Leave a Comment</h3> if(Yii::app()->user->hasFlash('commentSubmitted')): <div class="flash-success"> echo Yii::app()->user->getFlash('commentSubmitted'); </div> else: $this->renderPartial('/comment/_form',array( 'model'=>$comment, )); endif; </div><!-- comments -->
在上面的代码中,如果闪存消息可用,则显示它。否则,我们通过渲染局部视图 /wwwroot/blog/protected/views/comment/_form.php
来显示评论输入表单。
为了改善用户体验,我们可以使用基于 Ajax 的表单字段验证,以便在用户填写表单之前,在提交整个表单到服务器之前,向其提供验证反馈。为了在评论表单上支持基于 Ajax 的验证,我们需要对评论表单视图 /wwwroot/blog/protected/views/comment/_form.php
和 newComment()
方法进行一些小的修改。
在 _form.php
文件中,当我们创建 CActiveForm 小部件时,主要需要将 CActiveForm::enableAjaxValidation 设置为 true
<div class="form"> $form=$this->beginWidget('CActiveForm', array( 'id'=>'comment-form', 'enableAjaxValidation'=>true, )); ...... $this->endWidget(); </div><!-- form -->
在 newComment()
方法中,我们插入一段代码来响应 AJAX 验证请求。该代码检查是否存在名为 ajax
的 POST
变量。如果是,它将通过调用 CActiveForm::validate 来显示验证结果。
protected function newComment($post)
{
$comment=new Comment;
if(isset($_POST['ajax']) && $_POST['ajax']==='comment-form')
{
echo CActiveForm::validate($comment);
Yii::app()->end();
}
if(isset($_POST['Comment']))
{
$comment->attributes=$_POST['Comment'];
if($post->addComment($comment))
{
if($comment->status==Comment::STATUS_PENDING)
Yii::app()->user->setFlash('commentSubmitted','Thank you for your comment. Your comment will be posted once it is approved.');
$this->refresh();
}
}
return $comment;
}
发现错别字或您认为此页面需要改进?
在 github 上编辑它 !
后续...
错误点击提交...(顺便问一下,我如何编辑我的评论?)
所以
$url=$this->getController()->createUrl($this->captchaAction); CHtml::image($url,$alt,$this->imageOptions);
是重要的行。第一行创建当前控制器的操作,它将如下所示(带有 **get** 参数的默认 URL):**index.php?r=post/captcha**
此 URL 将用于指向 **验证码操作** CCaptchaAction,该操作实际上将在 gd 库的帮助下呈现图像(参见 CCaptchaAction 类的 renderImage 方法)。
但要使所有这些都能正常工作,您需要 **使此 URL 指向正确的操作**,这在 **PostController 的 actions 数组** 中完成(参见指南的 Controller 页面中的 Action 部分)。
/** * Declares class-based actions. */ public function actions() { return array( // captcha action renders the CAPTCHA image // this is used by the contact page 'captcha'=>array( 'class'=>'CCaptchaAction', 'backColor'=>0xF5F5F5, ), ); }
希望这对像我一样尝试在不查看完成的演示代码的情况下遵循教程的人有所帮助。
Comment 模型中的 verifyCode 变量
你好,
由于我花了 15 分钟试图弄清楚为什么应用程序返回
属性“Comment.verifyCode”未定义。
尝试设置新的 Comment 表单时
我认为在模型中必须为在同一模型中设置的每个验证规则存在一个变量。即,对于不是数据库字段的字段的验证规则。
示例
为了使此规则存在且没有任何错误返回
array('verifyCode', 'captcha', 'on' => 'insert', 'allowEmpty'=>!Yii::app()->user->isGuest)
以下行必须添加到 Comment 模型中
public $verifyCode;
也许在某个地方解释过,但如果是这样的话,我错过了信息 :)
希望对某人有所帮助
谢谢
是一个规则,
addComment
addComment 在帖子模型中
public function addComment($comment) { if(Yii::app()->params['commentNeedApproval']) $comment->status=Comment::STATUS_PENDING; else $comment->status=Comment::STATUS_APPROVED; $comment->post_id=$this->id; return $comment->save(); }
commentNeedApproval 的作用
我花了一段时间才弄清楚“commentNeedApproval”引用的那行代码发生了什么,所以我认为我会分享答案。
您必须在配置文件 main.php 中添加一个应用程序参数
return array( ... // application-level parameters that can be accessed // using Yii::app()->params['paramName'] 'params'=>array( ... 'commentNeedApproval'=>true, ),
效果很好!
为了发表评论,请注册或登录。