2

我正在开发一个 Joomla 组件,在 de 管理员部分有一个(非常常见的)网格视图。当我单击网格中某个项目的发布图标时,页面将重新加载,并且发布状态将更改为已发布/未发布。但是在重新加载页面后,我希望网格滚动到我单击发布图标时所处的滚动位置,这样我就可以看到我刚刚更改的项目。

我试图实现滚动位置的存储和恢复几乎完全类似于在页面加载之间存储/恢复搜索过滤器的方式:

1)在模板(views/mygrid/tmpl/default.php)中,我添加了一个隐藏字段:

<input type="hidden" name="page_scroll" value="0" id="page_scroll" />

2)在同一个文件中,我在表单的 onsubmit 属性中添加了一些代码来填充此字段:

<form id="adminForm" name="adminForm" method="post" onsubmit="document.getElementById('page_scroll').value = window.pageYOffset;">

3)在模型(models/mygrid.php,类从 JModelList 扩展)中,我将这些行添加到 populateState 函数中:

protected function populateState($ordering = null, $direction = null) {
  ..
  $pageScroll = $app->getUserStateFromRequest( $this->context.'.page.scroll', 'page_scroll', '0', 'string');
  $this->setState( 'page.scroll', $pageScroll );
  ..
}

4)在视图(views/mygrid/view.html.php,从JView扩展的类)中我在显示函数中添加了这一行:

function display($tpl = null) {
..
  $this->state = $this->get('State');
..
}

5)最后,回到模板(views/mygrid/tmpl/default.php),我在文件末尾添加了这个小脚本:

<script type="text/javascript">
  window.scrollTo( 0, <?php echo $this->state->get('page.scroll') ?> );
</script>

它对我来说看起来如此漂亮、干净和正确,但它只是拒绝工作。当我将以下调试行添加到最后一个脚本时,它总是给我 0:

alert( <?php echo $this->state->get('page.scroll') ?> );

有人可以告诉我我忽略了什么吗?我将不胜感激!

4

1 回答 1

0

在David Fritsch的鼓励下,我再次非常彻底地调试,找到了答案!不是一件事,而是两件事出了问题!对于有同样问题的人,或者为任何想要存储/恢复页面滚动的人完成本“手册”,我将解释:

1) 这第一件事是最重要的。当您在“mygrid”视图中应用过滤器时,表单被提交并立即再次加载相同的视图,但现在应用了新的过滤器。这就是为什么我的问题中的第 3 步适用于过滤器的原因。

但是...当您单击网格项目的发布状态时,表单已提交,但现在带有任务“mygriditem.publish”或“mygriditem.unpublish”!因此没有达到我回答的第 3 步,因为现在调用了“mygriditem”控制器而不是“mygrid”控制器。只有在那之后,页面才会第二次重新加载以重定向回“mygrid”视图。但是“page_scroll”不再出现在请求中!!

解决方案:我的问题中的第 3 步必须复制到 mygriditem 控制器的发布任务功能(controllers/mygriditem.php,类扩展自 JControllerForm),例如:

public function publish( $key = null, $urlVar = null )
{
    JFactory::getApplication()->getUserStateFromRequest( 'com_mycomponent.mygrid.page.scroll', 'page_scroll', '0', 'string' );

    return parent::publish( $key, $urlVar );
}

在使用“取消发布”功能做同样的事情之后,它就可以工作了!!

2)我还忽略了第二件事,这使它非常混乱:表单的 onsubmit 事件处理程序仅在单击提交按钮时执行,而不是在您使用 Javascript 提交表单时执行,例如:

onclick="this.form.submit()"

我觉得我应该保持简短。Joomla 提供了一个函数,让您可以在模板(views/mygrid/tmpl/default.php)中使用它:

onclick="submitform(task)"

请注意使用此函数(间接)提交 adminForm,然后将执行 onsubmit 事件处理程序。

我希望这对某人有帮助。:)

于 2013-09-20T20:08:15.480 回答