0 关注者

创建和显示评论

在本节中,我们将实现评论显示和创建功能。

为了增强用户互动性,我们希望在用户每次完成输入一个字段后提示其可能的错误。这被称为客户端输入验证。我们将展示如何在 Yii 中轻松无缝地完成此操作。请注意,这需要 Yii 版本 1.1.1 或更高版本。

1. 显示评论

我们不分别在各个页面上显示和创建评论,而是在帖子详情页面(由 PostControllerview 操作生成)上进行操作。在帖子内容显示下方,我们首先显示属于该帖子的评论列表,然后显示一个评论创建表单。

为了在帖子详情页面上显示评论,我们修改视图脚本 /wwwroot/blog/protected/views/post/view.php 如下所示:

...post view here...
 
<div id="comments">
    <?php if($model->commentCount>=1): ?>
        <h3>
            <?php echo $model->commentCount . 'comment(s)'; ?>
        </h3>
 
        <?php $this->renderPartial('_comments',array(
            'post'=>$model,
            'comments'=>$model->comments,
        )); ?>
    <?php endif; ?>
</div>

在上面,我们调用 renderPartial() 来渲染一个名为 _comments 的局部视图,以显示属于当前帖子的评论列表。请注意,在视图中,我们使用表达式 $model->comments 来检索帖子的评论。这是有效的,因为我们在 Post 类中声明了一个 comments 关系。评估此表达式将触发一个隐式 JOIN 数据库查询,以返回正确的评论。此功能称为 延迟关联查询

局部视图 _comments 并不复杂。它主要遍历每个评论并显示其详细信息。感兴趣的读者可以参考 /wwwroot/yii/demos/blog/protected/views/post/_comments.php

2. 创建评论

为了处理评论创建,我们首先修改 PostControlleractionView() 方法如下:

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>
 
    <?php if(Yii::app()->user->hasFlash('commentSubmitted')): ?>
        <div class="flash-success">
            <?php echo Yii::app()->user->getFlash('commentSubmitted'); ?>
        </div>
    <?php else: ?>
        <?php $this->renderPartial('/comment/_form',array(
            'model'=>$comment,
        )); ?>
    <?php endif; ?>
 
</div><!-- comments -->

在上面的代码中,如果闪存消息可用,则显示它。否则,我们通过渲染局部视图 /wwwroot/blog/protected/views/comment/_form.php 来显示评论输入表单。

3. 基于 Ajax 的验证

为了改善用户体验,我们可以使用基于 Ajax 的表单字段验证,以便在用户填写表单之前,在提交整个表单到服务器之前,向其提供验证反馈。为了在评论表单上支持基于 Ajax 的验证,我们需要对评论表单视图 /wwwroot/blog/protected/views/comment/_form.phpnewComment() 方法进行一些小的修改。

_form.php 文件中,当我们创建 CActiveForm 小部件时,主要需要将 CActiveForm::enableAjaxValidation 设置为 true

<div class="form">
 
<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'comment-form',
    'enableAjaxValidation'=>true,
)); ?>
......
<?php $this->endWidget(); ?>
 
</div><!-- form -->

newComment() 方法中,我们插入一段代码来响应 AJAX 验证请求。该代码检查是否存在名为 ajaxPOST 变量。如果是,它将通过调用 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 上编辑它 !