【问题标题】:Stopping reload timer for grid in ATK4在 ATK4 中停止网格的重新加载计时器
【发布时间】:2014-05-21 18:26:51
【问题描述】:

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

我已经实现的网格重新加载,如本线程 Agile toolkit : how to automatically reload grid 中所述

这是会员页面的代码:

<?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()函数有返回值,不知道怎么处理到ATK4框架中的clearInterval(id)函数?

【问题讨论】:

  • 你在 page_groups 类中哪里定义了 $details_grid 变量?
  • 是的,在这种情况下,您应该以某种方式从 setInterval 获取返回值并将其传递给 clearInterval。或者您可以尝试使用 setTimeout 而不是 setInterval,但 setTimeout 应该添加到网格而不是页面!这样 setTimeout JS 将在每​​次网格刷新时重新加载和重新加载并与网格一起重新加载。
  • 哎呀... $details_grid-&gt;grid 必须在 $grid 中更改。我已经更改了上面的代码。谢谢。 setInterval() 的返回值的问题是,我得到的不是 Id,而是 jQuery 代码的平安。 :-( 但我会尝试使用setTimeout 进行测试。感谢您的提示。
  • 好的,我尝试将setInterval() 部分替换为:$grid-&gt;js(true)-&gt;univ()-&gt;setTimeout($grid-&gt;js()-&gt;reload()-&gt;_enclose(), 10000); 但结果是一样的。也许,点击“X”后 frameURL 不会真正关闭/销毁,而只会隐藏!?
  • 好的,我创建了测试用例,你是对的。问题是 setInterval 在 HTML 页面“事件”中注册并继续重新加载所有以前打开的弹出窗口。我会尝试找到解决方案并在此处发布。

标签: atk4 agiletoolkit


【解决方案1】:

说明:

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

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

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

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

  • 使用 setTimeout 而不是 setInterval 并使用新的 setTimeout 每次调用重新加载小部件
  • 在关闭模式对话框窗口时使用 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 对象上。

【讨论】:

  • 是的,这太棒了。但至少需要从setInterval() 获取计时器ID 以供以后使用的方法。
  • 同时您可以查看与此解决方案相关的以下资源:stackoverflow.com/questions/13567634/…groups.google.com/forum/#!searchin/agile-toolkit-devel/…
  • 谢谢。我已经看到了这些讨论,但也许重点是,生成一个自己的网格类并将其放在那里。我会试试的。
  • OK 工作解决方案已准备好作为 ATK 的补丁。希望罗马人能接受并推入ATK分支。
  • @ATL 你能用来自 github 的最新 ATK4 提交来试试你的项目吗:github.com/atk4/atk4/commit/… 让我们知道这项工作是否适合你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-30
  • 1970-01-01
  • 2011-08-25
  • 1970-01-01
  • 2012-01-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多