2 votes

Yii2 ActiveDataProvider : résultat correct mais totalCount 0 dans le texte de synthèse

J'essaie de filtrer des données à l'aide d'une liste déroulante. La requête s'exécute parfaitement et produit un résultat toujours correct, mais dans le résumé, le compte total est toujours égal à 0, mais pas la première fois lorsque la page est chargée. Cela m'ennuie car je ne parviens pas à retracer l'erreur à l'aide de l'outil de débogage.

Mais ce qui est important, c'est que le même code fonctionne bien sur ma machine locale, alors que je l'ai déployé en production et qu'il affiche 0 compte.

Mon code modèle :

public function search($params) {

    $query = Tasks::find();

    $query->where(['q_id' => $this->job_id]);

    // $query->orderBy('created_at DESC');

    $dataProvider = new ActiveDataProvider([
        'query' => $query,
        'pagination' => [
            'pageSize' => 20,
        ],
    ]);

    $this->load($params);

    if (!empty($this->keyword) || $this->keyword != '') {

        $query->andWhere('MATCH(task_title,task_description, priority) AGAINST("' . $this->keyword . '*" IN BOOLEAN MODE)');
    }

    if (is_numeric($this->filterby)) {
        $query->andFilterWhere(['status' => $this->filterby]);
    } else {
        $query->andFilterWhere(['IN', 'status', [10, 4, 2]]);
    }

    if (!empty($this->sortby) || $this->sortby != '') {
        $query->orderBy($this->sortby . ' DESC');
    }

    return $dataProvider;
}

Voici mon code d'affichage :

<?php
yii\widgets\Pjax::begin(['id' => 'tasks-pjax', 'timeout' => 10000]);
echo \yii\widgets\ListView::widget([
    'layout' => '{summary}<br/>{items}{pager}',
    'dataProvider' => $dataProvider,
    'summary' => '<div class="col-lg-12 hidden-xs"><p class="text-muted text-success"> {totalCount} Tasks Found!</p></div>',
    'summaryOptions' => ['style' => 'margin-bottom: 5px;margin-top:5px;', 'tag' => 'span'],
    'id' => 'tasks-list',
    'itemOptions' => ['class' => 'task-item'],
    'emptyText' => 'No Task Found !',
    'emptyTextOptions' => ['class' => 'list-group-item', 'style' => 'margin-left: 15px; margin-right:15px; color: red'],
    'itemView' => '_tasks',
    'pager' => [
        'class' => 'kop\y2sp\ScrollPager',
        'container' => '#tasks-list',
        'item' => '.task-item',
        // 'next' => '.next a',
        'triggerOffset' => 20,
        'noneLeftText' => '',
    ]
])
?>
<?php yii\widgets\Pjax::end(); ?>

Code du contrôleur :

public function actionIndex() {

    $searchModel = new \frontend\models\TasksSearch();

    if (Yii::$app->request->get('q_id')) {
        $qModel = QPosts::findOne(['q_id' => base64_decode(Yii::$app->request->get('q_id'))]);
        $searchModel->q_id = $qModel->q_id;

        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        if (Yii::$app->user->identity->id == $qModel->user_id || Yii::$app->user->identity->id == $xxxModel->xxx_id) {
            return $this->render('index', [
                        'searchModel' => $searchModel,
                        'dataProvider' => $dataProvider,
                        'qModel' => $qModel,
            ]);
        } else {
            return $this->redirect(['xxxx/xxxx', 'id' => $qModel->q_id]);
        }
    } else {
        throw new NotFoundHttpException('The requested page does not exist.');
    }
}

0voto

e-frank Points 484

Pouvez-vous afficher le code de votre grille ? Y a-t-il une méthode pjax ? $dataProvider->models ?

quelques autres choses que j'ai remarquées, sans répondre à votre question initiale :

au lieu de

$query->orderBy($this->sortby . ' DESC');

essayer

$query->orderBy([$this->sortby => SORT_DESC]);

ou ce que je fais avec les états (ouvert/fermé/en attente/annulé, actif=ouvert ou en attente, inactif=fermé ou annulé) :

<?php
namespace common\models;
use Yii;

class Status
{
    const UNDEFINED = 0;
    const OPEN      = 1;
    const CLOSED    = 2;
    const CANCELLED = 4;
    const PENDING   = 8;

    const ACTIVE    = 9;
    const INACTIVE  = 6;

    static function asArray() {
        return [
            self::OPEN      => Yii::t('app', 'Open'),
            self::CLOSED    => Yii::t('app', 'Closed'),
            self::CANCELLED => Yii::t('app', 'Cancelled'),
            self::PENDING   => Yii::t('app', 'Pending'),
        ];
    }

    static function asFilter() {
        return [
            self::ACTIVE    => Yii::t('app', 'Active'),
            self::INACTIVE  => Yii::t('app', 'Inactive'),
            self::OPEN      => Yii::t('app', 'Open'),
            self::CLOSED    => Yii::t('app', 'Closed'),
            self::CANCELLED => Yii::t('app', 'Cancelled'),
            self::PENDING   => Yii::t('app', 'Pending'),
        ];
    }

}

dans la fonction search($params) :

if (!empty($this->status))
    $query->andWhere('task.status & :status = task.status', [':status' => $this->status]);

une colonne d'état personnalisée :

<?php
namespace common\grid;

use Yii;
use yii\helpers\Html;
use yii\helpers\Json;
use yii\helpers\ArrayHelper;
use yii\web\JsExpression;
use yii\web\View;
use yii\helpers\Url;
use common\models\Status;

class StatusColumn extends \yii\grid\DataColumn {

    public $attribute      = 'status';
    public $headerOptions  = ['class' => 'text-center', 'style' => 'width: 10em'];
    public $contentOptions = ['class' => 'text-center'];
    public $footerOptions  = ['class' => 'text-center'];

    private $sum1 = 0;
    private $sum2 = 0;

    public function renderDataCell($model, $key, $index) {
        $value      = $model->__get($this->attribute);
        $this->sum1 += ($value === null ? 0 : ($value & Status::ACTIVE ? 1 : 0));
        $this->sum2 += ($value === null ? 0 : ($value & Status::INACTIVE ? 1 : 0));
        return parent::renderDataCell($model, $key, $index);
    }

    protected function renderFooterCellContent() {
        $this->footer = sprintf('%d/%d', $this->sum1, $this->sum2);
        return parent::renderFooterCellContent();
    }

    public function init() {
        parent::init();

        if ($this->content === null) {
            $this->content = function($data, $key, $index) {
                $value = $data->__get($this->attribute);

                switch ($value) {
                    case Status::OPEN :
                        return sprintf('<div class="label label-primary">%s</div>', Yii::t('app', 'Open'));
                        break;

                    case Status::CLOSED :
                        return sprintf('<div class="label label-success">%s</div>', Yii::t('app', 'Closed'));
                        break;

                    case Status::CANCELLED :
                        return sprintf('<div class="label label-danger">%s</div>', Yii::t('app', 'Cancelled'));
                        break;

                    case Status::PENDING :
                        return sprintf('<div class="label label-info">%s</div>', Yii::t('app', 'Pending'));
                        break;

                    default:
                        return sprintf('<div class="label label-default">%s</div>', Yii::t('app', 'undefined'));
                        break;
                }

                return $value;
            };
        }

        if ($this->filter === null) {
            $this->filter = Status::asFilter(); 
        }

        if ($this->footer === null) {
            $sum1 = 0;
            $sum2 = 0;
            $this->footer = sprintf('%d/%d', $this->sum1, $this->sum2);
        }
    }
}

?>

et l'utiliser dans la grille :

    [
        'class' => 'common\grid\StatusColumn',
    ],

0voto

Steve M. Points 1

J'ai eu un problème similaire. Ma requête activerecord comportait un joinWith et j'avais oublié d'ajouter un groupBy dans la requête, ce qui dupliquait les lignes. J'utilisais le widget ListView et les {items} {pager} ou {summary} étaient erronés (j'ai oublié). Quoi qu'il en soit, l'ajout d'un groupBy dans ma requête avec un joinWith a résolu mon problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X