0

我正在测试 ATK4 以决定是否可以使用它。其中一个场景是组和成员的状态页面,它应该自动重新加载包含动态组和成员信息的网格。

我已经实现的网格重新加载,如 Thread Agile 工具包中所述:如何自动重新加载网格

这是会员页面的代码:

<?php 
class page_members extends Page { 
    function init(){ 
        parent::init(); 
        $page = $this; 

        $page->api->stickyGET('group_id'); 
        $grid = $page->add('Grid'); 
        $model = $grid->setModel('Member'); 
        if ($_GET['group_id']) 
            $model->addCondition('group_id', $_GET['group_id']); 
        $page->js(true)->univ()->setInterval( 
                $grid->js()->reload()->_enclose() 
                ,10000); 
    } 
} 

如果我使用group_id参数从浏览器调用它,它会像预期的那样工作。但是这个页面会从一个组页面调用到一个 frameURL 中,代码如下:

<?php 
class page_groups extends Page { 
    function init(){ 
        parent::init(); 
        $page = $this; 

        $grid = $page->add('Grid'); 
        $model = $grid->setModel('Group'); 
        $grid->addColumn('button','members'); 

        if($_GET['members']){ 
            $grid->js()->univ() 
                ->frameURL('Members' ,$page->api->url('../members',array('group_id'=>$_GET['members']))) 
                ->execute(); 
        } 

        $page->js(true)->univ()->setInterval( 
            $grid->js()->reload()->_enclose() 
            ,10000); 

    } 
} 

如果我单击第 1 组中的“成员”按钮,第 1 组的成员页面会在一个框架中打开并每 10 秒刷新一次。没关系。但是,如果我通过单击第 2 组中的“成员”按钮关闭框架并打开一个新框架,则网格会在刷新网格的同时循环通过第 1 组和第 2 组。

我认为,问题在于由函数创建的计时器,必须在框架关闭之前将setInterval()其清除。clearInterval(id)setInterval()函数有一个返回值,但我不知道如何将它处理到clearInterval(id)ATK4 框架中的函数?

4

1 回答 1

0

描述:

存在问题是因为setInterval添加到全局window对象并且因为window对象本身没有重新加载(使用 AJAX,我们只重新加载 DOM 树的一部分)setInterval即使您关闭模式对话框或重新加载“页面”容器,方法也会继续被调用。

总之写在这里:http ://www.w3schools.com/jsref/met_win_setinterval.asp

setInterval() 方法将继续调用该函数,直到调用 clearInterval() 或关闭窗口。

因此,在这种情况下,可能的解决方法将是以下之一:

  • 每次使用新调用来代替并重新加载小setTimeout部件setIntervalsetTimeout
  • 在关闭模式对话框窗口时使用clearInterval以摆脱旧的全局注册间隔

可以在这里找到很多关于 setInterval 的有用信息:https ://developer.mozilla.org/en/docs/Web/API/window.setInterval


测试用例:

class page_company extends Page
{
    function init()
    {
        parent::init();
        $page = $this;

        $grid = $page->add('Grid');
        $model = $grid->setModel('Company');
        $grid->addColumn('button','company');

        if ($_GET['company']) {
            $grid->js()->univ()
                ->frameURL('Employees', $page->api->url('../employee', array(
                    'company_id'=>$_GET['company'])))
                ->execute();
        }
    }
}

class page_employee extends Page
{
    function init()
    {
        parent::init();
        $page = $this;

        $page->api->stickyGET('company_id');
        $grid = $page->add('Grid');
        $model = $grid->setModel('Employee');
        if ($id = $_GET['company_id']) {
            $model->addCondition('company_id', $id);
        }

        // NOTE:Important is that you add setTimeout JS chain to grid not page!
        //      That's because you reload only grid and you need to receive
        //      this JS chain from server on each reload to keep it reloading.
        //      $page is not reloading, only $grid is!
        $grid->js(true)->univ()->setTimeout(
                $grid->js()->reload()->_enclose()
                ,5000);
    }
}

这样,除了关闭一个模式对话框并在不到 5 秒(setTimeout 时间)内打开新对话框的情况外,一切正常。问题是一样的 -setTimeout也被添加到全局window对象中,因此即使您同时关闭模态对话框,它仍然会在这 5 秒后执行。


上次编辑

借助 Github 中最新的 ATK 提交,您现在只需 1 个简单的链即可初始化任何视图的定期重新加载。

因此,不要像这样(不起作用):

$grid->js(true)->univ()->setTimeout(
            $grid->js()->reload()->_enclose()
            ,5000);

现在您可以简单地调用:

// reload grid every 5 seconds
$grid->js(true)->reload(null,null,null,5000);

注意:您应该将其应用于您想要定期重新加载的 View 对象。

于 2014-04-09T14:58:51.827 回答