Pull to refresh

Comments 35

Хотел написать «навигации», но она у меня ассоциируется с кнопками назад-вперед в браузере)
Просто устоявшийся термин это «пагинация» ну или «постраничная навигация».
Довольно сильно резануло.
«пагинация» тоже сильно режет ухо. Звучит как нечто из гинекологии :)
не возникало подобных ассоциаций =)
А это про недомобильную связь 90-х.
«постраничная навигация» мне нравится, сейчас поправлю.
спасибо!
А если в контроллере проверять на ajax и если он, то выдавать renderPartial('_grid'), а если нет, то render('index'), в котором уже renderPartial('_grid')?
Только хотел написать. Такой способ будет более логичен и не только для гридов, а так-же для всего остального ajax.
Для одного грида подойдет.
Но если actionIndex создает, к примеру, два грида? Придется наставить if'ов.
ну зачем же сразу ифов, что мешает называть файлы с гридами в соответствии с id этих гридов, которые передаются в гет-параметре ajax?
Зачем использовать «if»?
Можно сделать так:
    public function actionIndex()
    {
        $formsModel=new FormsMain('search');
        $fieldsModel=new FormsFields('search');

        switch(Yii::app()->getRequest()->getQuery('ajax'))
        {
            case 'formsListGridID'   : {
                            $formsModel->attributes=Yii::app()->getRequest()->getQuery('FormsMain');
                            $this->renderPartial('_formsListGrid',array('formsModel'=>$formsModel));
                            break;
                           }
            case 'fieldsListGridID'   : {
                            $fieldsModel->attributes=Yii::app()->getRequest()->getQuery('FormsFields');
                            $this->renderPartial('_fieldsListGrid',array('fieldsModel'=>$fieldsModel));
                            break;
                           }
            default: $this->render('main',array('formsModel'=>$formsModel,'fieldsModel'=>$fieldsModel)); break;
        }
    }

* This source code was highlighted with Source Code Highlighter.


Представление main.php с двумя CGridView:
    <table width="100%" cellpadding="0" cellspacing="1" class="contentList">
        <tr class="odd">
            <td>Forms</td>
            <td>Fields</td>
        </tr>
        <tr class="even">
            <td width="50%">
                            <? $this->renderPartial('_formsListGrid',array('formsModel'=>$formsModel)); ?>
            </td>
            <td width="50%">
                            <? $this->renderPartial('_fieldsListGrid',array('fieldsModel'=>$fieldsModel),false,false); ?>
            </td>
        </tr>
    </table>

* This source code was highlighted with Source Code Highlighter.
В целом я согласен с таким подходом, он работает.
Просто у меня страница с 5-ю блоками ))
Да хоть 10 ))
Главное, чтобы не тормозило и не огорчало того, кто этим будет пользоваться ))
Можно назвать это делом вкуса.
Мне вместо свича на 10 значений приятней иметь компактные action'ы, где в каждом решается конкретная задача.
Например, такие:
    public function actionGrid()
    {
        $dp = new CActiveDataProvider('Product', array(
        'sort' => array(
            'defaultOrder' => 'name asc',
        ),
        'pagination' => array(
            'pageSize' => 10,
        )
        ));

        $this->renderPartial('_grid', compact('dp'));
    }

Меня смущает что серверная логика всех компонентов собрана в одной функции.
А что если я захочу еще в другом месте сайта вывести тот же грид с пользователями?
вероятно получилось как-то так:
if(Yii::app()->request->isAjaxRequest)
{
$this->renderPartial(Yii::app()->request->getParam('ajax'), array('dataProvider' => $dp));
}
else
{
$this->controller->render('index', array('dataProvider' => $dp));
}


но как вы выбираете нужный dataProvider?
Да как угодно, можно вообще передавать все подряд, а можно использовать массив типа $models['first_model'] = $first_model; $models['second_model'] = $second_model; тогда

if(Yii::app()->request->isAjaxRequest)

{

$grid_name = Yii::app()->request->getParam('ajax')

$this->renderPartial($grid_name, array('model' => $models[$grid_name]));

}

else

{

$this->controller->render('index', $models);

}
Вообще у нас грид используется как правило в админках, где нет большого количества запросов, так что такого рода оптимизациями можно пренебречь. Но идея интересная.
Прочитал, но не понимаю, почему у меня работает по другому, а не так как Вы описали в Способ 2. Все через Ajax

Вот action, который выводит список пользователей:
<?
class UsersList extends CAction
{
    public function run()
    {
    $model=new User('search');
    if(Yii::app()->getRequest()->getQuery('User')) $model->attributes=$_GET['User'];

        if(Yii::app()->getRequest()->getQuery('ajax'))//проверка "а есть ли в запросе призрак ajax'a"
        {
            $this->controller->renderPartial('usersListGrid',array('model'=>$model));
        }
        else
        {
       $this->controller->render('usersList',array('model'=>$model));
        }
  }
}


* This source code was highlighted with Source Code Highlighter.


Вышеописанный action рендерит представление usersList.php, которое в свою очередь вызывает usersListGrid.php.

Если же потом мы будем переходит по страницам, фильтровать, сортировать, то CGridView подставит в запрос ajax и вышеописанный action будет отдавать только представление usersListGrid.php (чистый html-код, без всяких вызовов jquery.js и остальных скриптов), так как они уже были загружены при первом вызове.

И все будет работать.

Представление: usersList.php
<table width="100%" cellpadding="0" cellspacing="1">
    <tr>
        <td><?=$this->renderPartial('usersListGrid',array('model'=>$model),true,false); ?></td>
    </tr>
</table>

* This source code was highlighted with Source Code Highlighter.

Представление: usersListGrid.php
<table width="100%" cellpadding="0" cellspacing="0">
<tr class="even1">
    <td>
        <?=CHtml::beginForm($this->createUrl("admin/itemsSelected"),'post',array('enctype'=>'multipart/form-data')); ?>
        <? $this->widget('zii.widgets.grid.CGridView', array(
          'id'=>'usersListGrid',
          'dataProvider'=>$model->search(),
          'selectableRows'=>3,
          'template'=>"{summary}<br />{pager}<br />{items}<br />{pager}<br />",
          'pager'=>array(
                  'class'=>'CLinkPager',
                'header'=>'',
                'firstPageLabel'=>'<<',
                'prevPageLabel'=>'<',
                'nextPageLabel'=>'>',
                'lastPageLabel'=>'>>',
                 ),
          'filter'=>$model,
          'columns'=>array(
            array(
              'class'=>'CCheckBoxColumn',
              'id'=>'itemsSelected',
            ),
            array(
              'name'=>'id',
              'value'=>'$data->id',
              //'filter'=>'',
              'htmlOptions' => array('style' => 'text-align:center;width:40px;'),
            ),
            array(
              'name'=>'datreg',
              'type'=>'raw',
              'value'=>'date("d/m/Y H:i:s",$data->datreg)',
              'filter'=>'',
              'htmlOptions' => array('style' => 'text-align:center;width:130px;'),
            ),
            array(
              'class'=>'CButtonColumn',
              'template'=>'{myupdate} {mydelete}',
              'htmlOptions' => array('style' => 'width:30px;'),
              'buttons'=>array(
                'myupdate'=>array(
                  'label'=>'Редактировать',
                  'url'=>'array("admin/usersEdit","id"=>$data->id)',
                  'imageUrl'=>Yii::app()->theme->baseUrl.'/img/pencil.png',
                ),
                'mydelete'=>array(
                  'label'=>'Удалить',
                  'url'=>'array("admin/usersDelete","id"=>$data->id)',
                  'imageUrl'=>Yii::app()->theme->baseUrl.'/img/minus.png',
                  'click'=>'function(){return confirm("'.Yii::t('lan','Удалить ?').'");}',
                  'visible'=>'$data->role!=User::ROLE_ADMIN',
                ),
              ),
            ),

          ),
        ));
        ?>
        С отмеченными: <?//=CHtml::DropDownList('workWithItemsSelected',null,$model->WorkItemsSelected,array('empty' =>'--')); ?>
        <?=CHtml::submitButton('Выполнить',array('onclick'=>"return confirm('?');")); ?>
        <?=CHtml::endForm(); ?>
    </td>
</tr>
</table>


* This source code was highlighted with Source Code Highlighter.
Все правильно, это скорее способ 3, т.к. первый раз у вас грид загружается не через ajax.
Но что если на этой же странице вам потребуется второй грид, например, со списком прав пользователя?
@vitalets, увидел статью и уже хотел тебе ссылку отправить… но, дочитав до середины, понял, что где-то я уже всё это слышал :)
Да, решил разобраться уже с этим вопросом. При встрече обсудим)
Спасибо. Всегда когда надо делаю 3-м способом, но, адаптированным. В демоблоге вроде хороший пример был грида + ajax...(или в gii, точнее не смогу сказать).
А как поступаете с route'ом для сортировки и навигации? как в примерах выше или, может, более красиво?
Обычно все стандартно делаю. В редких случаях jquery.bbq.js применяю для обработок ссылок вперед-назад и хранения инфы в адресной строке о порядке сортировки и текущей странице.
Как же отключить повторную загрузку скриптов? Для этого можно поставить отдельный extension, который при ajax-запросах вырезает скрипты, уже загруженные на странице… Но лично я ожидаю от Yii решения этой задачи стандартными средствами, без расширений…


Есть вот такая интересная штука, правда ручками надо все скрипты отключить. Можно использовать маски.

        /** @var $cs CClientScript */
        $cs = Yii::app()->clientScript;

        $cs->scriptMap['jquery.js'] = false;
        $cs->scriptMap['jquery.min.js'] = false;
        $cs->scriptMap['jquery.qtip-1.0.0-rc3.min.js'] = false;
        $cs->scriptMap['cart.js'] = false;

        $cs->scriptMap['main.css'] = false;


	$this->controller->renderPartial('_supergrid', array(
            'bla_bla' => $bla_bla
	), false, true);
if(!Yii::app()->request->isAjaxRequest) throw new CHttpException('Url should be requested via ajax only');


Вот для этого довольно удобно использовать фильтр ajaxOnly
NlsClientScript Поддерживает только одиночную загрузку скриптов.
Sign up to leave a comment.

Articles