モデルgetListQuery()はJPaginationを使用してすべての行をフェッチします


7

モデルにgetListQuery()メソッドがあり、クエリを返します。私たちが知っているように、JoomlaはJPaginationを使用するときにクエリの制限とオフセットを自動的に設定します。JPaginationを使用してgetListQuery()ですべての行をフェッチしたいという問題があります。限り、私は次のようなコードを書きました

protected function getListQuery(){

    // here is created my $query object with query

    // I'm fetching all rows
    $rows = $db->loadObjectList();
    $this->rows = $rows;

    return $query;

}

つまり、クエリは2回実行されます。1つはこのメソッドで、もう1つはJoomlaコアです。ページの読み込みが2倍長くなるため、このソリューションにはあまり満足していません。クエリには約10の結合があります...何百万もの行があるため、それは本当に問題です。正しい解決策はありますか?

回答:


6

私は解決策を見つけました(私は思う)。JModelListメソッドを上書きしました。

class MyComponentModel extends JModelList{

    protected $_items = array();

    public function getItems() {
        // Get a storage key.
        $store = $this->getStoreId();

        // Try to load the data from internal storage.
        if (isset($this->cache[$store])) {
            return $this->cache[$store];
        }
        $query = $this->getQuery();
        $this->query = $query;
        $db = JFactory::getDbo();
        $db->setQuery($query);
        $rows = $db->loadObjectList();
        $this->cache[$store] = $rows;
        $this->_items = $rows;
        return array_slice($rows, $this->getStart(), $this->getState('list.limit'));
    }

    public function getPagination() {
        // Get a storage key.
        $store = $this->getStoreId('getPagination');

        // Try to load the data from internal storage.
        if (isset($this->cache[$store])) {
            return $this->cache[$store];
        }

        // Create the pagination object.
        jimport('joomla.html.pagination');
        $limit = (int) $this->getState('list.limit') - (int) $this->getState('list.links');
        $page = new JPagination($this->getTotal(), $this->getStart(), $limit);

        // Add the object to the internal cache.
        $this->cache[$store] = $page;

        return $this->cache[$store];
    }

    function getTotal() {
        return count($this->_items);
    }

    public function getQuery() {
        // query
        return $query;
    }

}

view.html.php

$this->model = $this->getModel();
$this->items = $this->model->getItems();
$this->pagination = $this->model->getPagination();

ページの読み込みがはるかに速くなります。それは良い解決策ですか?


なぜすべての行が必要なのですか?$this->_itemsこの場合、何をしますか?
David Fritsch 2014

私は選択した場所をマーカーとして使用したグーグルマップを持っているので、データベースから調整を取得するためにすべての行をフェッチし、ページネーションを使用していくつかの行を表示し
たいと思いました

これでも、ページが読み込まれるたびにすべての結果が読み込まれることは間違いありません。キャッシュは、ページのロード間で変数を格納しません。joomlaのデフォルトの方法がうまく機能するように感じます。(おそらく私は何かが欠けていることを意味します...)
David Fritsch

はい、ページが読み込まれるたびにすべての結果が読み込まれますが、私の意見では、クエリを2回実行してページ
分割が正常に

20とだけ言う必要がある場合は、すべての行をロードしないでください。次のコマンドを使用してデータをロードします。$ db-> setQuery($ query、$ start、$ limit); カウントを取得:$ this-> _ getListCount($ query);
ed22

4

JoomlaはgetItemsクエリの実行に使用する必要があります。したがって、最善の策は、モデルの状態を変更して、すべての結果が確実に読み込まれるようにすることです。

モデル内では、次のsetStateように使用してこれを行うことができます。

$this->setState('list.limit', 0);

モデルがgetItemsを呼び出す前にそれを実行すると、すべてのアイテムが読み込まれます。


これに関するいくつかの警告。

  1. モデルの外でこれを行うこともできるので、たとえば、ビュー内にいた場合。次のことができます。

    $ model = $ this-> getModel(); $ model-> setState( 'list.limit'、0);

  2. 場合によっては、モデルの状態が入力される前にこれを行うのが早すぎる可能性があります。これにより、制限を設定した後、基本的に制限をオーバーライドして、モデルがユーザーの状態から再構築されます。

これを修正するには、最初にモデルに強制的にその状態を入力させることができます。

$model = $this->getModel();
$model->getState();
$model->setState('list.limit', 0);

実際のpopulateStateメソッドは保護されているため、モデルの外では直接呼び出すことはできませんが、への呼び出しは、状態の現在の設定を返す前にが呼び出されるgetStateことを確認しpopulateStateます。


返信ありがとうございます。残念ながら、まだ目標には達していません。私のview.html.php:$this->model = $this->getModel(); $this->model->getState(); $this->model->setState('list.limit', 0); $this->pagination = $this->get('Pagination'); $this->items = $this->get('Items'); $this->state = $this->get('State');クエリにより、1ページにすべての行がロードされます
turson '29

うーん...誤解しました。すべての行が必要だと思いました。実際にすべての行を利用したいが、それでも一部の行を表示したいですか?
David Fritsch 2014

すべての行をフェッチして(そして変数に格納して)同時にページ
分割

しかし、すべての行で何をしていますか?何のために保管していますか?
David Fritsch 2014

Googleマップで調整を取得してマーカーを設定するには、すべての行が必要です。地図上はすべてマーカーでなければなりません。
turson 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.