Как реорганизовать процесс AJAX в Yii

Мне нужна помощь в рефакторинге или в дизайне :). Я сделал свое веб-приложение, оно работает хорошо. Но я до сих пор плохо понимаю процесс Ajax в Yii. Например, когда я использую метод $.fn.yiiGridView.update(), я вижу этот результат на всей веб-странице, а не только на содержимом CGridView. Мне было интересно.

Но теперь: в индексном представлении я использую CGridView, но без пейджера! Это простое веб-приложение для ставок. И на index.php я просматриваю только 10 ставок/результатов на странице, и через 10 секунд я просматриваю следующие 10 ставок/результатов и снова следующие 10 результатов/ставок через 10 секунд :), с JavaScript.

Этот простой процесс:

  1. вызывается actionIndex(), он отображает index.php (index.php содержит JS-коды дизайна, но не CGridView, где веб-приложение просматривает результаты)
  2. index.php отображает содержимое файлов _ajaxIndex.php.
  3. Код JS вычисляет следующие 10 результатов, которые нужно будет просмотреть на веб-странице.
  4. вызывается actionAjaxIndex(). Это дает обновленное содержимое _ajaxIndex.php, повторяющееся с 3. снова.
  5. Код JS снова вычисляет следующие 10 результатов...

Примечание. Пока администраторы вставляют результаты на веб-страницу администратора, веб-приложение должно отображать временные результаты. Вот почему мне нужно обновить сводку и раундовые переменные JS в _ajaxIndex.php.

Контроллер

/**
     * Lists all models.
     */
public function actionIndex() {
    Yii::app()->language='hu';

    $model = new Result('search');
    $model->unsetAttributes();

    if (isset($_GET['Result']))
        $model->attributes = $_GET['Result'];

    if (isset($_POST['offset']) && $_POST['offset'] >= 0)
        $model->offset = $_POST['offset'];  

    $summary = Result::getCountSavedResults();
    $model->isLimited = true;
    $this->layout='projector'; 

    $this->render('index', array('model' => $model, 'summary'=>$summary));
    //$this->actionAjaxIndex();
}

/**
 * List all models by Ajax request.
 */    
public function actionAjaxIndex() {
    Yii::app()->language='hu';

    $model = new Result('search');
    $model->unsetAttributes();  // clear any default values

    if (isset($_GET['Result']))
        $model->attributes = $_GET['Result'];

    if (isset($_POST['offset']) && $_POST['offset'] >= 0)
        $model->offset = $_POST['offset'];  

    $summary = Result::getCountSavedResults();
    $model->isLimited = true;

    $this->renderPartial('_ajaxIndex', array('model' => $model, 'summary'=>$summary));
}

Я хотел бы прекратить повторение этого кода в actionIndex(). Но я понятия не имею, как я могу это сделать... Я пытался вызвать actionAjaxIndex и т. д. Но прежде чем я смог вызвать actionAjaxIndex, я получил ошибки PHP от Yii. (Суммарная переменная не существует и т. д.)

Просмотр — Index.php

<!--<h1><?php echo Yii::t('strings','Results'); ?></h1>-->
<?php 
    echo CHtml::image(Yii::app()->request->baseUrl.'/images/toplista.jpg', "Fogadás");
?>
<script type="text/javascript">
    // Initialize the variables for calculating
    var summary = <?php echo $summary ?>; // get all stored results
    var timeout = 10 * 1000; // in Milliseconds -> multiply with 1000 to use seconds
    var current = 0;
    var turn = 0;
    var rounds = Math.floor(summary / 10);
</script>

<?php $this->renderPartial('_ajaxIndex', array('model'=>$model, 'summary'=>$summary)); ?>

<script type="text/javascript">

    // Refresh the CGridView's content in _ajaxIndex.php
    window.setInterval("refresh()", timeout);
    // Get the offset to the search() to set the criteria
    // Increase turn.
    function counter(){
        turn += 1;

        if(turn > rounds){
            turn = 0;
        }
        return turn *10;
    }

    function refresh() {       
        <?php
        echo CHtml::ajax(array(
                'url'=> CController::createUrl("result/ajaxIndex"),
                'type'=>'post',
                'data'=> array('offset'=>'js: counter()'),
                'replace'=> '#ajax-result-grid',
                ))
        ?>
    }
</script>

Просмотр — _ajaxIndex.php

<?php
/* @var $model Result */
?>
<?php $this->widget('zii.widgets.grid.CGridView', array(
        'id'=>'ajax-result-grid',
        'dataProvider'=>$model->search(),       
        'columns'=>array(
                array(
                    'header'=>Yii::t('strings','No.'),
                    'value'=> $model->offset.' + $row+1',
                    'htmlOptions'=>array('style'=>'width:50px;'),
                 ),
                array(
                    'header'=>Yii::t('strings','team_name'),
                    'name'=>'team_id',
                    'value'=>'$data->team->name'
                ),
            array(
                    'header'=>Yii::t('strings','value'),
                    'name'=>'value',
                    'value'=>'$data->value'
                ),

        ),
)); ?>

<script type="text/javascript">
    // This is need while the admins insert the results during this page is run.
    summary = <?php echo $summary ?>;
    rounds = Math.floor(summary / 10);
</script>

Да, мне кажется, я плохо понимаю процесс Ajax в Yii :/.


person blaces    schedule 17.09.2013    source источник


Ответы (1)


На самом деле вы уже сделали огромный шаг вперед, используя один и тот же шаблон — _ajaxIndex.php — как для вызовов AJAX, так и для начальной загрузки страницы. Но да, вы можете пойти еще дальше в этом направлении, используя одно действие.

В этом действии должна быть проверка того, как именно вызывается метод, через AJAX или нет. В зависимости от результатов вы либо отображаете всю страницу целиком, либо только ее часть.

Обычно эта проверка делается так же просто, как...

if (Yii::app()->request->isAjaxRequest) { ... }

Но здесь есть проблема: эта проверка зависит от пользовательского заголовка HTTP HTTP_X_REQUESTED_WITH, используемого многими библиотеками JS, реализующими свои собственные процедуры AJAX. К сожалению, некоторые прокси-серверы сбрасывают этот заголовок, поэтому он может быть ненадежным. Чтобы быть на 100% уверенным, просто укажите другой параметр в помощнике AJAX (самый простой — ajax), а затем проверьте этот параметр (тоже).

person raina77ow    schedule 17.09.2013
comment
Ах спасибо за помощь :). Я сейчас попробую isAjaxRequest(). :). - person blaces; 18.09.2013