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

Javascript "Yii";“每页结果”;在同一页面中加载其他ajax内容后,ajax下拉列表会中断,javascript,jquery,gridview,yii,Javascript,Jquery,Gridview,Yii,我在Yii中有一个视图,即“Patients”视图,它包含许多cgridview和其他元素,这些元素在加载初始视图后被ajax加载。有些是在已经加载了ajax的div中加载的ajax,这意味着它们嵌套在两个级别的深处 在这些ajax加载的cGridView中,我有下拉菜单,允许用户设置每个网格中每页的结果数。在用户使用ajax在页面上加载另一个元素之前,这一切都很正常。ajax加载另一个网格(或任何其他网格)后,它会中断每个页面的所有其他结果ajax函数,除了刚才加载的结果 使用ajax加载任何

我在Yii中有一个视图,即“Patients”视图,它包含许多cgridview和其他元素,这些元素在加载初始视图后被ajax加载。有些是在已经加载了ajax的div中加载的ajax,这意味着它们嵌套在两个级别的深处

在这些ajax加载的cGridView中,我有下拉菜单,允许用户设置每个网格中每页的结果数。在用户使用ajax在页面上加载另一个元素之前,这一切都很正常。ajax加载另一个网格(或任何其他网格)后,它会中断每个页面的所有其他结果ajax函数,除了刚才加载的结果

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

类型错误:设置未定义

内置的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,
));
?>
/$columns[]=“正常等位基因深度”;
//$columns[]=“正常等位基因频率”;
回声“;
回显“每页结果:”。
CHtml::dropDownList('gecgPageSize',$gecgPageSize,数组(10=>10,20=>20,50=>50100=>100),数组(
“onchange'=>”
$.fn.yiiGridView.update('gecg',{data:{gecgPageSize:$(this.val()}});
",
));
回声“;
$this->widget('zii.widgets.grid.CGridView',数组(
'id'=>'gecg',
“过滤器”=>$model,
“dataProvider”=>$dataProvider,
“columns'=>$columns,
));
?>

想法?

我不确定你写的东西我都拿到了,但是你有信心两个深度的寻呼机加载了
CGridView
的工作吗

Yii使用jQuery的方法将事件处理程序附加到寻呼机的按钮、排序按钮和类的按钮。如果指定
selector
参数,则在调用时,将为jQuery元素的所有匹配子体触发事件
on()
方法,包括现有和不存在的子体

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

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视图的
文档
元素。

解决方案:经过大量的混乱之后,我决定手动将
设置
+
$.fn.yiiGridView
存储在每个inlineSearch视图末尾的窗口变量中,然后,当“每页我的项目”选择器更改时,从窗口检索它们

这不是一个非常优雅的解决方案(特别是因为寻呼机工作正常,它将导致多个$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>";

我确信寻呼机在所有ajax加载的网格中都能工作,即使在重新加载其他网格之后也是如此。我正在尝试使网格设置成为全局设置,或在每次网格加载后附加到文档。但仍然不确定最好的方法是什么。谢谢。作为补充说明,我后来不得不修改CGridView框架代码,以避免多次重新加载该小部件时产生重复事件。虽然不是最优的,但它不是为通过ajax内联加载而设计的。
<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>