0

Here is the problem,

Server responds with several records in JSON, which number is greater than grid pageSize parameter specified in the Store. The total number is not returning by a server in this JSON with data. The number of such records is known and could be different (this number should be requested from the server in another request). The total number is needed for the pagingtoolbar.

How to tell the proxy reader this number from the view controller?

The only workable solution I found is to override the Ext.data.reader.Json reader with the following code:

Ext.define('MyApp.custom.AnotherReader',{
    extend: 'Ext.data.reader.Json',
    alias : 'reader.anotherReader',

    // разбираем ответ и записываем в store
    getResponseData : function(response) {
        var st = Ext.decode(response.responseText);
        st.total = 5;
        //console.log(st);
        return st;
    }
});

The problem is I cannot dynamically change this total parameter from the viewcontroller.

JSON 1:

[
  {
    "id":"1",
    "user_id":"11",
  },
  {
    "id":"2",
    "user_id":"12",
  },
  {
    "id":"3",
    "user_id":"13",
  },
  {
    "id":"4",
    "user_id":"14",
  },
  {
    "id":"5",
    "user_id":"15",
  }
]

JSON 2:

{
  "records_count": "5"
}
fen1ksss
  • 1,100
  • 5
  • 21
  • 44
  • You don't have control over the server response? – Yellen Apr 28 '15 at 16:33
  • You already have a hold of the array (or the JSON that holds your array) in your `getResponse` function. Why not do `st.total = the_array_for_your_store.length`? – SelfSurgery Apr 28 '15 at 16:53
  • I've already mentioned, the number of rows is greater than grid pageSize parameter specified in the Store. That's why I have only a part of all records in the Store in the specific moment, dependent on limit and offset. – fen1ksss Apr 28 '15 at 16:59
  • What do you want to happen if the number of rows > pageSize? Do you want to display all of the rows anyway? That will happen by default since pageSize doesn't affect anything except the parameters you send in your requests. Do you want to truncate your array? Then use `array.splice` – SelfSurgery Apr 28 '15 at 17:10
  • IMHO, I don't think this makes any sense. You're already getting all the data from the server. Setting a total count after you've received the data does not seem to be logical. Can you please tell why you need to set the total count after you've received the data? Is it for total items to display in grid? – Yellen Apr 28 '15 at 17:12
  • @fen1ksss - I think it'd be good if you could mention your final requirement. – Yellen Apr 28 '15 at 17:13
  • @SelfSurgery - if rows > pageSize I want to show them on several pages, that's why I need total number - for correct pagination using pagingtoolbar, sorry for not mentioning this, I thought it is logical. – fen1ksss Apr 28 '15 at 17:17
  • @Seram - please see my answer to SelfSurgery – fen1ksss Apr 28 '15 at 17:18
  • @fen1ksss - 1. If possible you could use bufferedRenderer: true in your grid - This will not only render a part of the records with some buffer and fetch remaining records for render when you scroll (if you are using Ext 5.x) [Increases grid performance as well] 2. http://docs.sencha.com/extjs/5.0/5.0.1-apidocs/#!/api/Ext.ux.data.PagingMemoryProxy - You could pass all your loaded data as data to a PagingMemoryProxy in your store – Yellen Apr 28 '15 at 17:28
  • Why I'm suggesting the other options is because whenever you try to load your data from the proxy for a page, you are anyway going to get the whole set of data - that kind of beats the purpose of pagination – Yellen Apr 28 '15 at 17:30
  • I might be wrong but this is my opinion. :) – Yellen Apr 28 '15 at 17:32
  • Further reading - http://extjs.eu/example-grid-memory-paging/ – Yellen Apr 28 '15 at 17:39
  • @Seram, thank you for your suggestions, "whenever you try to load your data from the proxy for a page, you are anyway going to get the whole set of data - that kind of beats the purpose of pagination" this is actually not true, to load another page I need to send another request for the server, with different "offset" parameter. I think bufferedRenderer parameter is doing kind of the same thing, asking server for another pack of data using the same offset parameter. To do so it needs the total. – fen1ksss Apr 28 '15 at 17:48
  • **bufferedRenderer: true** : The whole data set is loaded once, but not all the records are rendered when your grid is rendered - This somehow enhances the first load of the table - Imaging 1k records in loaded and you had to render all even though you are displaying 100 at a time!!! BufferedRenderer only renders 100 + some offset and the subsequent records are rendered when you scroll. This will cause some problems if you are intending to use the LiveSearchGrid plugin available in the examples. – Yellen Apr 28 '15 at 17:52
  • Why I'm saying it beats the purpose of pagination in your case is - As I understand from you statement, the whole set of data will be loaded on each page change. Basically, you'll be loading all data but you'll only be using part of it to display on the grid. Server side pagination means that only the data for the specified page should be loaded. Also, in your case where you can't change the way server is producing the data- it'll be best, in my opinion, to use PaginMemoryProxy. – Yellen Apr 28 '15 at 17:56
  • Or is it that each page request will give you a different set of data? Forgive me, but from your statement it sounds like the whole set data is returned. If each page request returns different page data then what is the problem in setting the pagSize? Are you saying that the pageSize sent from the server is dynamic? – Yellen Apr 28 '15 at 17:59
  • @Seram, there may be thousands of records, that's why I need every page to be loaded from the server in a small pack. – fen1ksss Apr 28 '15 at 18:02
  • @Seram, "Or is it that each page request will give you a different set of data", sure it is, for example, server can return 1000 unique records, I want to show those records by 20, that's why I set pageSize: 20. Every time I click the next page, the new request goes to the server with offset parameter and loads the new pack of 20 records. The pagination needs to know how many pages count to show in the bar. To do that it requires the "total" parameter. Total / pageSize - number of the pages. But how to set that Total, gotten not from JSON with data is a question. – fen1ksss Apr 28 '15 at 18:06
  • @fen1ksss - One last confirmation - so, if you send an offset of, say, 20, and the page Number, say, 4 then your server will return only 20 records for the second page? – Yellen Apr 28 '15 at 18:08
  • I'm not using pages, just an offset, to your question, it will be possibly a bad request – fen1ksss Apr 28 '15 at 18:26
  • 1
    OK, this link will help you - http://stackoverflow.com/questions/14254321/best-practice-for-overriding-classes-properties-in-extjs – Yellen Apr 29 '15 at 06:20

1 Answers1

1

You can do this inside your controller -

    // some event handler/ or normal function inside your Controller that you'll call
    somFunction: function() {
        var me = this;
        var store = Ext.getStore(<storeId>); // you can even pass the store 
//instance as a parameter to this function
        var reader = store.getProxy().getReader();
        Ext.override(reader, {
            getResponseData : function(response) {
                var st = Ext.decode(response.responseText);
                st.total = me.getValueYouWant();
                return st;
            }
        });
    }
Yellen
  • 1,785
  • 16
  • 35
  • Thank you for the idea of overriding! one thing is I need to override store.proxy.reader instead of the store. – fen1ksss Apr 29 '15 at 09:41