问题
This is a follow up question that I got answered here: How can I programmatically set column filters?
I have a 188 line Ext.js view. In this view I extend Ext.grid.Panel
and in this grid I have set the selModel like so ...
selModel: {
cellSelect: false, // Only support row selection.
type: 'spreadsheet' // Use the new "spreadsheet" style grid selection model.
},
On one of the columns, the Status
column, I am programmatically setting the filter so that only rows that have the Status
of Ready
will appear when the page firsts renders. I have been doing this here in the code:
columns: [
...
{
text: 'Status',
dataIndex: 'status',
itemId: 'status',
renderer: function(value, metaData) {
var filter = this.up('panel').down('#status').filter;
if (!filter.menu) {
filter.createMenu();
filter.menu
.down('menuitem[value="Ready"]')
.setChecked(true);
}
metaData.tdStyle = (value == 'Ready') ?
'color:green;font-weight: bold' :
'color:red;font-style: italic'
return(value)
},
filter: 'list',
flex: 1,
},
... more columns ...
A helpful SO member pointed out that is not the most efficient place for the code that sets the filter as the code will be executed for each row in the grid.
I have tried adding an afterrender
function like so ...
{
text: 'Status',
dataIndex: 'status',
itemId: 'status',
renderer: function(value, metaData) {
metaData.tdStyle = (value == 'Ready') ?
'color:green;font-weight: bold' :
'color:red;font-style: italic'
return(value)
},
filter: 'list',
flex: 1,
listeners: {
afterrender: function(value) {
Ext.Msg.alert('We have been rendered value is ' + value );
var filter = this.up('panel').down('#status').filter;
if (!filter.menu) {
filter.createMenu();
filter.menu
.down('menuitem[value="Ready"]')
.setChecked(true); //Uncaught TypeError: Cannot read property 'setChecked' of null
}
}},
... but that results in this error message, //Uncaught TypeError: Cannot read property 'setChecked' of null
.
What am I doing wrong here? Do I need the listeners:
? Am I not getting passed the data I think I am getting passed to my afterrender
function? Should I defining a initComponent
function?
UPDATE:
I changed my code to what DrakeES suggested, ...
{
text: 'Status',
dataIndex: 'status',
itemId: 'status',
renderer: function(value, metaData) {
metaData.tdStyle = (value == 'Ready') ?
'color:green;font-weight: bold' :
'color:red;font-style: italic'
return(value)
},
flex: 1,
filter: {
type: 'list',
value: 'Ready'
}
... but the result is this:

Where the animated loading
image just sits there and spins. This prevents the user from be able to change the filter interactively. I wonder what it is I am doing wrong here?
回答1:
I am programmatically setting the filter so that only rows that have the Status of Ready will appear when the page firsts renders
What checking the filter's checkbox effectively does is setting filter on the store. Because you want the filter to be applied initially, it would be better to have it in the store config right away:
filters: [
{
id: 'x-gridfilter-status',
property: 'status',
value: 'Ready'
}
]
That way the grid view appear filtered in the first place — instead of initially showing all rows and only then filtering them out once the column menu renders and applies the filter. Note that having id: 'x-gridfilter-status'
on the store's filter is required so that the column's filter picks it up instead of creating a duplicate.
Setting filter on the store, however, will not send feedback to the column filter menu, so the latter will remain unchecked unless you explicitly check it. Therefore, you still need an afterrender
handler on either the grid or the column to make things look in sync.
A simple and elegant solution without listeners and stuff:
filter: {
type: 'list',
value: 'Ready'
}
Full working example: https://fiddle.sencha.com/#fiddle/prp
来源:https://stackoverflow.com/questions/31190820/where-to-programmatically-set-column-filters-when-using-a-spreadsheet-selmodel