Home > Article > Web Front-end > An in-depth analysis of how to use the store grouping function in Extjs_javascript skills
During the project practice, I encountered the requirement to group the data in the grid according to a certain field. Of course, this function is available in the API and is listed here for everyone to find:
Two points to note:
1. When creating a store, you need to set the value of the groupField attribute, which 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, then 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 for group display
JavaScript code
var groupingFeature= Ext.create('Ext.grid.feature.Grouping',{ groupHeaderTpl: 'sex: {name} ({rows.length} Item{[values.rows.length > 1 ? "s" : ""]})' });//注意其中{name}即为store中sex列所对应的值
In gridPanel, the code is as follows: Configure features as the 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 rendering is as follows:
Of course, after grouping is implemented, the sex column in the 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 the 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 shown below
It can be seen that the interface is not what we want, so how to solve it? (The initial stupid solution was that I removed the gridPanel, destroyed it, and reloaded it) I made some changes to the code for listeners to listen to events
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, grouping must also be implemented instead of appending the data to the end of the gridPanel. The difference between these two pieces of code mainly lies in the method of adding data to the store. The former is add(record) and the latter is loadData(records,[append])
At first, I couldn’t understand why the same store added data, but the effect was different. See the explanation in the official documentation, add(), The new Model instances will be added at the end of the existing collection. (Add data to the collection. Finally) I suddenly realized that loadData loads data according to the rules of the store.
In addition, how to remove the oldest row in the group, I checked it myself, the document has been implemented, and I will share it with you here:
//Modify the previous listeners listening events as follows:
Pay attention to the first([boolean group]) method. If no parameters are passed, the first data in the store will be obtained. When the parameter is true, the store group will be returned with the group name key and the first data in the group. One piece of data is multiple objects of value. PersonStore.first(true).female gets the first piece of data in the female group. If you want to get the data in 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 prevent removedRecords from occupying memory, further processing has been carried out. The function can be implemented, but the method is a bit clumsy. If anyone has a good way, we can 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);//这句有没有都可以 PersonStore.loadRecords(recs);//重新load数据,内存中记录的removed掉的就没有了 console.log(PersonStore); alert(PersonStore.getRemovedRecords.length);//这句alert结果为0 // console.log(PersonStore.getAt(0)); } }