Mô hình getListQuery () tìm nạp tất cả các hàng bằng cách sử dụng JPagination


7

Tôi có phương thức getListQuery () trong mô hình của mình, trả về truy vấn. Như chúng ta đã biết, Joomla tự động đặt giới hạn và bù cho truy vấn khi chúng ta sử dụng JPagination. Tôi có một vấn đề, đó là tôi muốn sử dụng JPagination và tìm nạp tất cả các hàng trong getListQuery (). Theo như tôi đã viết mã như

protected function getListQuery(){

    // here is created my $query object with query

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

    return $query;

}

Điều đó có nghĩa là, truy vấn đang thực hiện 2 lần: một theo tôi trong phương thức này và một theo lõi Joomla. Tôi không hài lòng lắm với giải pháp này, vì nó khiến tải trang lâu hơn gấp 2 lần. Truy vấn có khoảng 10 lần tham gia ... Với hàng triệu hàng, điều đó thực sự có vấn đề. Bạn có thấy giải pháp nào đúng không?

Câu trả lời:


6

Tôi tìm thấy một giải pháp (tôi nghĩ). Tôi đã ghi đè lên các phương thức 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();

tải trang nhanh hơn nhiều. Là một giải pháp tốt?


Tại sao bạn cần tất cả các hàng? Bạn đang làm gì $this->_itemstrong trường hợp này?
David Fritsch

Tôi có bản đồ google với vị trí được chọn làm điểm đánh dấu, vì vậy tôi muốn tìm nạp tất cả các hàng để có được sự phối hợp từ cơ sở dữ liệu và sử dụng phân trang để hiển thị một số hàng
turson

Tôi khá chắc chắn rằng điều này vẫn tải tất cả các kết quả mỗi lần tải trang. Bộ nhớ cache không lưu trữ biến giữa các lần tải trang. Tôi cảm thấy như phương pháp mặc định của j Joomla sẽ hoạt động tốt. (Điều này có nghĩa là tôi đang thiếu thứ gì đó ...)
David Fritsch

Có, nó tải tất cả các kết quả mỗi lần tải trang, nhưng theo ý kiến ​​của tôi, trang web tải nhanh hơn trước đó khi tôi thực hiện truy vấn hai lần và phân trang hoạt động tốt
turson

Không tải tất cả các hàng nếu bạn chỉ cần nói 20. Tải dữ liệu với: $ db = $ this-> getDbo (); $ db-> setQuery ($ truy vấn, $ bắt đầu, $ giới hạn); Được tính với: $ this -> _ getListCount ($ truy vấn);
ed22

4

Joomla nên được sử dụng getItemsđể chạy truy vấn. Vì vậy, cách tốt nhất của bạn là thay đổi trạng thái của mô hình để đảm bảo rằng nó tải tất cả các kết quả.

Trong mô hình, bạn có thể làm điều này bằng cách sử dụng setStatenhư vậy:

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

Chạy nó trước khi mô hình gọi getItems và nó sẽ tải tất cả các mục cho bạn.


Một vài hãy cẩn thận với điều này.

  1. Bạn cũng có thể làm điều này bên ngoài mô hình, vì vậy, ví dụ nếu bạn ở trong chế độ xem của bạn. Bạn có thể làm như sau:

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

  2. Đôi khi bạn có thể thực hiện việc này quá sớm, trước khi trạng thái của mô hình được tạo ra, điều này sẽ khiến mô hình được xây dựng lại từ trạng thái người dùng sau khi bạn đặt giới hạn, về cơ bản ghi đè giới hạn.

Để khắc phục điều này, bạn có thể buộc mô hình đưa vào trạng thái của nó trước:

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

populateStatePhương thức thực tế được bảo vệ, do đó, bên ngoài mô hình bạn không thể gọi trực tiếp, nhưng bất kỳ cuộc gọi nào getStatecũng sẽ đảm bảo rằng cuộc populateStategọi được gọi trước khi trả về các cài đặt hiện tại ở trạng thái.


Cảm ơn đã trả lời. Thật không may, tôi đã không đạt được mục tiêu của tôi chưa. My 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');nó gây ra truy vấn tải tất cả các hàng tại một trang
turson

Hmm ... tôi đã hiểu lầm. Tôi nghĩ bạn muốn TẤT CẢ các hàng. Bạn thực sự muốn tất cả các hàng có sẵn nhưng vẫn chỉ muốn hiển thị một số hàng?
David Fritsch

Tôi muốn tìm nạp tất cả các hàng (và lưu trữ chúng trong một biến) và sử dụng phân trang cùng một lúc
turson

Nhưng bạn đang làm gì với tất cả các hàng? Bạn đang lưu trữ chúng để làm gì?
David Fritsch

Tôi cần tất cả các hàng để có được sự phối hợp và đặt điểm đánh dấu trên google map. Trên bản đồ phải là tất cả các điểm đánh dấu.
turson
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.