我在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,
));
?>
思想?
答案 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>