1

控制器中有两个动作:

C简介:

public function actionCProfile()
{
$model=$this->loadModel(Yii::app()->user->id);
$model->scenario = 'updateProfile';
$this->performAjaxValidation($model);

if(isset($_POST['User'])){
    $model->attributes=$_POST['User'];

    if($model->validate())
        if($model->save()){
            if(Yii::app()->request->isAjaxRequest)
                Yii::app()->end('saved');
            else{
                Yii::app()->user->setFlash('status','saved');
            }
        }

    if(Yii::app()->request->isAjaxRequest)
        if(!$model->validate())
            Yii::app()->end('!validate');
}

if(Yii::app()->request->isAjaxRequest)
    $this->renderPartial('_cprofile',array('model'=>$model));
else
    $this->render('update',array('model'=>$model,'form'=>'_cprofile'));
}

CPass:

public function  actionCPass()
{
$model = $this->loadModel(Yii::app()->user->id);
$model->scenario = 'CPass';
$this->performAjaxValidation($model);

if(isset($_POST['User'])){
    $model->attributes = $_POST['User'];
    if($model->validate()){
        if($model->verifyPassword($model->currentPass)){
            $model->changePassword($model->newPass);
            Yii::app()->end('changed');
        }
    }
}

if(Yii::app()->request->isAjaxRequest)
    $this->renderPartial('_cpass',array('model'=>$model));
else
    $this->render('update',array('model'=>$model,'form'=>'_cpass'));
}

和三个视图文件:

更新.php:

<?php
$cs = Yii::app()->clientScript;
$cs->registerCssFile('/x/css/myDetailview.css');
$cs->registerCssFile('/x/css/upanel/user-profile.css');
$url = Yii::app()->getBaseUrl().'/js/upanel.js';
$cs->registerScriptFile($url,CClientScript::POS_HEAD);

?>

<div id='user-profile-menu'>
    <ul>
        <li><?php echo CHtml::link('profile',Yii::app()->createUrl('/upanel/user/CProfile'),array('id'=>'profile-change-link')) ?></li>
        <li><?php echo CHtml::link('change email',Yii::app()->createUrl('/upanel/user/CPass'),array('id'=>'pass-change-link')) ?></li>
    </ul>
</div>

<div id='container'>
<?php $this->renderPartial($form,array('model'=>$model)); ?>
</div>

_cprofile.php:

<div class="form" >
        <?php
        $form = $this->beginWidget('CActiveForm',array(
            'id'=>'change-profile-form',
            'enableAjaxValidation'=>true,
            'enableClientValidation'=>true,
            'action' => 'index.php?r=upanel/user/cprofile',
            'method' => 'post',
            'clientOptions'=>array(
                'validateOnSubmit'=>true,
                'validateOnChange'=>true,
                'validateOnType'=>false,
            ),
        ));
        ?>

.
.
.
        <div class="row">
            <?php
                $url=Yii::app()->createUrl('upanel/user/CProfile');
                echo CHtml::ajaxSubmitButton('update',$url,
                    array(
                        'type'=>'POST',
                        'data'=>"js:$('#change-profile-form').serialize()",
                        'success'=>'callback',
                        'beforeSend'=>'before',
                    ),
                    array(
                        'id'=>'update-button',
                        'class'=>'submit-button',
                    )
                );
            ?>
        </div>
        <?php $this->endWidget() ?>

<?php echo $form->errorSummary($model,'resolve following errors: ') ?>

_cpass.php:

<div class="form">
        <?php
        $form = $this->beginWidget('CActiveForm',array(
            'id'=>'change-pass-form',
            'enableAjaxValidation' => 'true',
            'action' => Yii::app()->createUrl('upanel/user/CPass'),
            'method' => 'POST',
            'clientOptions' => array(
                'validateOnSubmit' => true,
                'validateOnChange' => true,
                'validateOnType' => false,
            )
        ));
        ?>

.
.
.
        <div class="row">
            <?php
          $url=Yii::app()->createUrl('upanel/user/CPass');
                echo CHtml::ajaxSubmitButton('update',$url,
                    array(
                        'type'=>'POST',
                        'data'=>"js:$('#change-pass-form').serialize()",
                        'success'=>'callback',
                        'beforeSend'=>'before',
                    ),
                    array(
                        'id'=>'update-button',
                        'class'=>'submit-button',
                    )
                );
            ?>
        </div>
        <?php $this->endWidget() ?>

</div> <!-- End Password Form -->
<?php echo $form->errorSummary($model) ?>

*编辑#1:*

看,我有一个view名为的页面update.php,在这个页面中有两个链接:

<div id='user-profile-menu'>
<ul>
    <li><?php echo CHtml::link('profile',Yii::app()->createUrl('/upanel/user/CProfile'),array('id'=>'profile-change-link')) ?></li>
    <li><?php echo CHtml::link('Change Password',Yii::app()->createUrl('/upanel/user/CPass'),array('id'=>'pass-change-link')) ?></li>
</ul>

以下 JQuery 代码运行存在actions于 中controller,结果是renderpartial()这些视图文件之一:_cpass.php_profile.php

$('document').ready(function(){

$('#profile-change-link').click(function(){
    var link = $(this).attr('href');
    $('#container').load(link);
    return false;
})

$('#pass-change-link').click(function(){
    var link = $(this).attr('href');
    $('#container').load(link);
    return false;
})

});

在控制器CProfile动作中定义为default action. 使用此操作,POST 和 Ajax 方法中的哪一个没有任何问题。

但主要问题:在该_cpass.php视图替换为_profile并已发送存在form于处理遇到问题的操作中_profileCPass问题是这样的:

预期的以下代码的输出是1

    public function  actionCPass()
{
    $model = $this->loadModel(Yii::app()->user->id);
    $model->scenario = 'CPass';
    $this->performAjaxValidation($model);

    if (1==1)
        Yii::app()->end('1');
}

但是以下代码的输出并不是我们所期望的。返回值是一个renderpartial()视图_profile。而动作代码中没有任何关于_cprofile视图的相关CPass代码!

    public function  actionCPass()
{
    $model = $this->loadModel(Yii::app()->user->id);
    $model->scenario = 'CPass';
    $this->performAjaxValidation($model);

    if(isset($_POST['User'])){
        $model->attributes = $_POST['User'];
        if($model->validate()){
            if($model->verifyPassword($model->currentPass)){
                $model->changePassword($model->newPass);
                Yii::app()->end('changed');
            }
        }
    }

    if(Yii::app()->request->isAjaxRequest)
        $this->renderPartial('_cpass',array('model'=>$model));
    else
        $this->render('update',array('model'=>$model,'form'=>'_cpass'));
}

上述代码的输出:

<div class="form" >

        <form id="change-profile-form" action="index.php?r=upanel/user/cprofile" method="post">
.
.
.                      
        <div class="row">

            <input id="update-button" class="submit-button" type="submit" name="yt0" value="update" />        </div>

        </form>

</div> <!-- End The Profile Form  -->

<div id="change-profile-form_es_" class="errorSummary" style="display:none">resole following errors:
<ul><li>dummy</li></ul></div>

现在明白是什么问题了吗?问题仅存在于Ajax请求中,当在浏览器中禁用javascriptCPass时,该操作真正起作用。

对不起,如果首先解释得很糟糕。

谢谢朋友


*编辑#2:*

使用 Firebug 进行调试时,我注意到 JQuery 代码片段没有改变。

首次进入default actioncontroller代码时:

$this->renderPartial('_cprofile',array('model'=>$model));

运行以下 JQuery 代码将创建:(如您所知,以下代码与CHtml::ajaxSubmitButton相关)

$('body').on('click','#update-button',function(){jQuery.ajax({'type':'POST','data':$('#change-profile-form').serialize(),'success':callback,'beforeSend':before,'url':'/x/index.php?r=upanel/user/CProfile','cache':false});return false;});

因此,当视图使用方法进行_cpass渲染时,上面的 JQuery 代码必须更改但不会更改。我想它一定是下面的代码:renderpartial()CPass

$('body').on('click','#update-button',function(){jQuery.ajax({'type':'POST','data':$('#change-cpass-form').serialize(),'success':callback,'beforeSend':before,'url':'/x/index.php?r=upanel/user/CPass','cache':false});return false;});

所以我的问题是为 CHtml::ajaxSubmitButton 生成的 JQuery 代码。谁能帮我?

4

3 回答 3

2
  1. 重命名一个/两个按钮 ID。这意味着事件处理程序将附加到不同的按钮。
  2. renderPartial('view.path',array(parameter_array),false,true);通过 Ajax 返回视图时使用。在适当位置插入所需客户端脚本的CController::renderPartial()调用的最后一个参数。CController::processOutput()
于 2013-04-11T18:51:25.590 回答
2

解决了

通过为ajaxSubmitButton应用uniqueId并在Controller Action中设置为True解决了。CController::processOutput()

摘要代码:

行动CPass:

public function  actionCPass()
{
$model = $this->loadModel(Yii::app()->user->id);
$model->scenario = 'CPass';
$this->performAjaxValidation($model);

if(isset($_POST['User'])){
    $model->attributes = $_POST['User'];
    if($model->validate()){
        if($model->verifyPassword($model->currentPass)){
            $model->changePassword($model->newPass);
            Yii::app()->end('changed');
        }
    }
}

if(Yii::app()->request->isAjaxRequest)
    $this->renderPartial('_cpass',array('model'=>$model),false,true);
else
    $this->render('update',array('model'=>$model,'form'=>'_cpass'));
}

_cpass.php:

            .
            .
            .
            <?php
            echo CHtml::ajaxSubmitButton(
                'update',
                Yii::app()->createUrl('upanel/user/CPass'),
                array(
                    'type'=>'POST',
                    'data'=>"js:$('#change-pass-form').serialize()",
                    'success'=>'callback',
                    'beforeSend'=>'before',
                ),
                array(
                    'id'=>'update-button'.uniqid(),
                    'class'=>'submit-button',
                )
            );
            .
            .
            .
        ?>
于 2013-04-12T00:01:52.877 回答
1

我想我理解你的问题,你想知道为什么页面没有周围的<div id='profile-container'>and </div>

我认为这可能与渲染函数只能在每个调用的视图中运行一次有关(因此它只渲染内部视图),您可以通过从更新页面中删除 renderPartial 并查看它是否打印空白来测试它分区。

解决此问题的一种方法是,不要进行两次渲染,而是始终调用每个页面(即使在 ajax 请求中),但如果它是 ajax 请求,则传递一个额外的属性。然后在每个页面上开始和结束一个自定义小部件,其中包含您在这些页面上想要的周围模板(或者只是手动编写)。

示例: 控制器

public function actionCProfile()
{
    // ... same as your example
    if(Yii::app()->request->isAjaxRequest){
        $this->renderPartial('_cprofile',array('model'=>$model, 'wasAjax'=>false));
    } else {
        $this->renderPartial('_cprofile',array('model'=>$model, 'wasAjax'=>true));
    }
}

然后在您的视图中检查 wasAjax 是否为真,如果是则打印周围的 div(或额外元素)。如果这很大或以后可能会更改,请将其放入自定义小部件中。

于 2013-04-09T15:15:17.327 回答