Frage

I'm testing ATK4 for some scenarios to decide, if I can go with it. One of these Scenarios is a status page for groups and members, which should reload automatically the grids, which contains dynamic group and member informations.

The grid reload I've implemented like described in this Thread Agile toolkit : how to automatically reload grid

Here's the code for the members page:

<?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); 
    } 
} 

If I call it from the Browser with the group_id parameter, it works like expected. But this page will called from a group page into a frameURL with the following code:

<?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); 

    } 
} 

If I click on button 'members' from group 1, the members page for group 1 open in a frame and refreshes every 10 seconds. That's okay. But if I close the frame and open a new frame by clicking on 'members' button from group 2, the grid cycling through group 1 and 2 while refreshing the grid.

I think, the problem is the timer, created by the setInterval() function, which has to be cleared by clearInterval(id) before the frame is closed. The setInterval() function has a return value, but I don't know, how I can handle it over to the clearInterval(id) function in the ATK4 Framework?

War es hilfreich?

Lösung

Description:

Problem exists because setInterval is added to global window object and because window object itself is not reloaded (using AJAX we only reload parts of DOM tree) setInterval method continues to be called even when you close modal dialog or reload "page" container.

In short it is written here: http://www.w3schools.com/jsref/met_win_setinterval.asp

The setInterval() method will continue calling the function until clearInterval() is called, or the window is closed.

So, possible workarounds in this case will be one of these:

  • use setTimeout instead of setInterval and reload widget with new setTimeout call every time
  • use clearInterval when you close modal dialog window to get rid of old globally registered intervals

A lot of useful information about setInterval can be found here: https://developer.mozilla.org/en/docs/Web/API/window.setInterval


Testcase:

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);
    }
}

This way everything works fine except situation when you close one modal dialog and open new one in less that 5 seconds (setTimeout time). Problem is the same - setTimeout also is added to global window object and as result it still get executed after these 5 seconds even if you close your modal dialog in the mean time.


Last Edit

With newest ATK commit in Github you can now initialize periodic reloads of any View with just 1 simple chain.

So instead of something like this (which don't work):

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

now you can simply call:

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

NOTE: you should apply this to exactly that View object which you want to reload periodically.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top