During the process of project practice, we encounter the requirement that the data in grid is grouped according to a certain field. Of course, this function is available in the API, and it is listed here for everyone to find:
Two things to note:
1. When creating a store, you need to set the value of the groupField attribute, that is, the value that needs to be grouped.
for example:
JavaScript Code
Ext.define('Person', { extend: 'Ext.data.Model', fields: ['name', 'sex'] });In this data model, we need to group by gender (sex), so please see the store below
JavaScript Code
var PersonStore = Ext.create('Ext.data.Store', { storeId: 'PersonStore', model: 'Person', groupField: 'sex', data: [{ name: 'hongmei li', sex: 'female' },{ name: 'san zhang', sex: 'male' },{ name: 'Jim Green', sex: 'male' },{ name: 'Lily', sex: 'female' },{ name: 'Lucy', sex: 'female' }] });Next, we need to define the tpl displayed in the group
JavaScript Code
var groupingFeature= Ext.create('Ext.grid.feature.Grouping',{ groupHeaderTpl: 'sex: {name} ({rows.length} Item{[values.rows.length > 1 ? "s" : ""]})' });//Note that {name} is the value corresponding to the sex column in the storeIn gridPanel, the code is as follows: Configure features to groupingFeature defined above
JavaScript Code
var grid = Ext.create('Ext.grid.Panel', { renderTo: Ext.getBody(), store: PersonStore, width: 600, height: 400, title: 'Person', features: [groupingFeature], columns: [{ text: 'Name', flex: 1, dataIndex: 'name' },{ text: 'sex', flex: 1, dataIndex: 'sex' }] });The renderings are as follows:
Of course, after implementing grouping, the sex column in gridPanel does not need to be displayed.
It should be noted that if the data in the store changes, can the grouping be displayed normally?
Now add an itemclick event to grid, the code is as follows:
JavaScript Code
listeners:{ itemclick:function(thisview,record){ PersonStore.<span style="color:#ff0000;">add</span>([{name:"li",sex:"male"},{name:"zhang",sex:"female"}]); } }The effect is as follows
It can be seen that the interface is not what we want, so how to solve it? (The stupid solution at the beginning was that I removed and destroyed this gridPanel, reloaded) I made some transformations of the code that listened to the event by listening to listeners
JavaScript Code
listeners:{ itemclick: function (thisview,record){ PersonStore.loadData([{name: "li" ,sex: "male" },{name: "zhang" ,sex: "female" }], true ); } }Look at the effect again:
This is the effect we want. When dynamically changing the data in the store, the grouping must also be implemented, rather than appending the data to the end of the gridPanel. Corresponding to the distinction between these two pieces of code, the main thing is the method of adding data in the store. The former is add(record) and the latter is loadData(records,[append])
At first I couldn't understand why the store added data, but the effect was different. I read the explanation of the official document, add(), The new Model instances will be added at the end of the existing collection. (Add data at the end of the collection) I suddenly realized that loadData loads the data according to the store rules.
In addition, how to remove the oldest line in the group, I checked it myself, and the document has been implemented. I will share it with you here:
//Modify the previous listeners listening event as follows:
Note that the first([boolean group]) method, if the parameter is not passed, the first data in the store is obtained. When the parameter is true, the return is a store group with the group name key and the first data in the group is value. PersonStore.first(true).female gets the first data in the female group. If you want to obtain the male, you can use PersonStore.first(true).male
JavaScript Code
listeners:{ itemclick: function (thisview,record){ PersonStore.loadData([{name: "li" ,sex: "male" },{name: "zhang" ,sex: "female" }], true ); alert(PersonStore.first( true ).female.get( 'name' )); console.log(PersonStore.first( true ).female); PersonStore.remove(PersonStore.first( true ).female); // console.log(PersonStore.getAt(0));} }In order to avoid the memory occupancy of removedRecords, further processing was carried out. The function can be implemented, but the method is a bit stupid. Everyone has a good way to communicate.
Look at the code:
listeners:{ itemclick:function(thisview,record){ PersonStore.loadData([{name:"li",sex:"male"},{name:"zhang",sex:"female"}],true); alert(PersonStore.first(true).female.get('name')); console.log(PersonStore.first(true)); PersonStore.remove(PersonStore.first(true).female); var recs = PersonStore.getRange(); console.log(recs); //PersonStore.removeAll(true);//Anything can be done with this sentence PersonStore.loadRecords(recs);//Reload the data, and the removed recorded in memory will be gone console.log(PersonStore); alert(PersonStore.getRemovedRecords.length);//This sentence alert result is 0 // console.log(PersonStore.getAt(0)); } }