Yii“每页结果”ajax下拉列表在同一页面中加载其他ajax内容后中断

时间:2012-11-14 21:08:56

标签: javascript jquery gridview yii

我在Yii中有一个视图,“患者”视图,它有许多CGridViews和其他元素,这些元素在加载初始视图后加载了ajax。有些是在已加载ajax的div中加载的ajax,这意味着它们嵌套了2层深度。

在这些加载了ajax的CGridViews中,我有一些下拉菜单,让用户可以设置每个网格中每页的结果数。这工作正常,直到用户使用ajax加载页面上的另一个元素。在ajax加载另一个网格(或其他任何内容)之后,它会破坏每页ajax函数的所有其他结果,除了刚刚加载的那个。

在使用ajax加载任何其他内容后,其他CGridViews会在使用每页结果下拉列表时抛出此javascript错误:

TypeError:设置未定义

内置的CGridView寻呼机始终适用于所有网格,所以我知道必须有一些方法让我的每页结果选择器找到正确的$ .fn.yiiGridView进行更新。

加载cgridview内联的控制器操作:

public function actionInlineSearch()
{
   YiiSessions::model()->setFromRequestCookie();

    $model=new GeneExpressionCufflinksGene('search');
    $model->unsetAttributes();  // clear any default values 
    // page size drop down changed

    if (isset($_GET['gecgPageSize'])) {
        Yii::app()->user->setState('gecgPageSize',(int)$_GET['gecgPageSize']);
        unset($_GET['gecgPageSize']);  // would interfere with pager and repetitive page size change
    }
    $gecgPageSize=Yii::app()->user->getState('gecgPageSize');

    if(isset($_REQUEST['GeneExpressionCufflinksGene']))
        $model->attributes=$_REQUEST['GeneExpressionCufflinksGene'];

    $this->renderPartial('inlineSearch',array('model'=>$model,'gecgPageSize'=>$gecgPageSize), false, true);
}

加载CGridView小部件的inlineSearch视图:

 // $columns[]='normal_allele_depth';
// $columns[]='normal_allele_freq';

echo "<div class='results-selector'>";
echo "Results per page: ". 
    CHtml::dropDownList('gecgPageSize',$gecgPageSize,array(10=>10,20=>20,50=>50,100=>100),array(
        'onchange'=>"
            $.fn.yiiGridView.update('gecg',{ data:{gecgPageSize: $(this).val() }});
        ",
    ));
echo "</div>";

$this->widget('zii.widgets.grid.CGridView', array(
   'id'=>'gecg',
   'filter'=>$model,
   'dataProvider'=>$dataProvider, 
   'columns'=>$columns,
));
?>

思想?

2 个答案:

答案 0 :(得分:0)

我不确定我是否收到了你所写的所有内容,但你是否确信两个深度加载CGridView的寻呼机有效?

Yii使用jQuery的CButtonColumn方法将事件处理程序附加到寻呼机的按钮,排序按钮,.on()类的按钮。如果指定selector参数,那么将调用jQuery元素on()方法的所有匹配后代的事件,对于此调用时现有和不存在的方法都会被调用。

Yii将处理程序附加到页面上始终存在的document元素(并且必须存在以允许触发事件)。您可以在CGridView中的init zii/widgets/assets/gridview/jquery.yiigridview.js方法中将其视为示例:

settings.updateSelector = settings.updateSelector
    .replace('{page}', pagerSelector)
    .replace('{sort}', sortSelector);

gridSettings[id] = settings;

if (settings.ajaxUpdate.length > 0) {
    $(document).on('click.yiiGridView', settings.updateSelector, function () {
        // Check to see if History.js is enabled for our Browser
        if (settings.enableHistory && window.History.enabled) {
            // ...
        } else {
            $('#' + id).yiiGridView('update', {url: $(this).attr('href')});
        }
        return false;
    });
}

所以我想如果你在ajax请求上渲染CGridView小部件,那么寻呼机,排序等的所有事件处理程序都将附加到ajax页面的部分呈现的document元素,但不会附加到你的那个新加载的元素将属于的主页面。如果您通过ajax加载inlineSearch视图,则下拉列表可能会发生同样的情况。

这就是为什么,正如我所看到的,所有事件处理程序必须附加到最初加载页面的主非ajax视图的document元素。

答案 1 :(得分:0)

解决方案:经过大量的讨论后,我决定在每个inlineSearch视图的末尾手动隐藏settings + $.fn.yiiGridView的窗口变量,然后在每个项目的每个项目中从窗口中检索它们页面选择器已更改。

这不是一个非常优雅的解决方案(特别是因为寻呼机工作正常,它会导致多个$ .fn.yiiGridView实例浮动)但是哦。它有效,虽然我在Yii仍然是一个菜鸟,但我可以通过我的研究告诉我,多个ajax加载的小部件存在一些未解决的问题。

inlineSearch视图中每页元素的新结果:

echo "<div class='results-selector'>";
echo "Results per page: ". 
    CHtml::dropDownList('gecgPageSize',$gecgPageSize,array(10=>10,20=>20,50=>50,100=>100),array(
        'onchange'=>"
            $.fn.yiiGridView=window.gecgGridView; // necessary in case other other ajax load doesn't have the yiigridview js
            $.fn.yiiGridView.settings['gecg']=window.gecgGridSettings; // because it will have been clobbered by other ajax grid load
            $.fn.yiiGridView.update('gecg',{ data:{ gecgPageSize: $(this).val() }});
        ",
    ));
echo "</div>";

在inlineSearch视图的末尾,这会在settings

中保存window
<script type='text/javascript'>
$(function(){ 
    window.gecgGridView=$.fn.yiiGridView;
    window.gecgGridSettings={
                            ajaxUpdate:["gecg"],
                            ajaxVar:"ajax",
                            pagerClass:"pager",
                            filterClass:"filters",
                            loadingClass:"grid-view-loading",
                            pageVar:"GeneExpressionCufflinksGene_page",
                            pagerClass:"GeneExpressionCufflinksGene_page",
                            selectableRows:1,
                            tableClass:"items",
                            updateSelector:"#gecg .pager a, #gecg .items thead th a",
                            afterAjaxUpdate:function(){}
                          };
})
</script>