简体   繁体   中英

ExtJS Add filtering in Grid for hasMany association

I have a data model that I want to be able to add a generic amount of filters to. I am specifying a name and a value. How can I add these hasMany associated fields as filters to my grid? I have attempted to write custom filtering option, but I can't have filters show up without an attached dataIndex, which is not available for the hasMany association.

Ext.define('AirGon.model.Project', {
    extend: 'Ext.data.Model',
    fields: [
        { name: 'Link', type: 'string' },
        { name: 'Title', type: 'string' },
        { name: 'Description', type: 'string' },
        { name: 'MappedMetadata', mapping: 'Metadata'},
        { name: 'XMax', type: 'float' },
        { name: 'XMin', type: 'float' },
        { name: 'YMax', type: 'float' },
        { name: 'YMin', type: 'float' }
    ],
    hasMany: { model: 'Metadata', name: 'Metadata', associationKey: 'Metadata' }    
});

Ext.define('Metadata', {
    extend: 'Ext.data.Model',
    fields: ['Name', 'Value']
});

This is my custom filtering attempt. I am getting the DataStore from the main store and then adding custom rendering, but I can't filter or sort this column because of the lack of a dataIndex.

var column = {
                header: 'Meta',
                //?????????dataIndex: 'MappedMetadata[0]',????? 
                sortable: true,
                filterable: true,
                filter: {
                    type: 'string'
                },
                renderer: function (value, meta, record) {
                    console.log(record.MetadataStore.data.items[index].data)
                    return record.MetadataStore.data.items[index].data.Value;
                }
            }

Data. The data is modeled so that a variable amount of metadata can be entered and the 'tag' will not be known by the system.

{
      "Link": "link.com",
      "Title": "project",
      "Description": "descript",
      "State": "",
      "Metadata": [
         {
            "Name": "County",
            "Value": "32"
         },
         {
            "Name": "Info",
            "Value": "info"
         },
         {
            "Name": "State",
            "Value": "TN"
         }
      ],
      "XMin": "-1",
      "XMax": "-1",
      "YMin": "1",
      "YMax": "1"
   } 

I was able to solve this by dynamically flattening the data model and adding columns once the store has been loaded. Although this breaks the MVC structure this was the best solution I came up with so it might be able to help you.

var defaultColumns = [];
var store = Ext.getStore('store');

        store.on('load', function (store) {
            var model = store.model;
            var fields = model.getFields();
            store.getAt(0).MetadataStore.data.items.forEach(function (item, index) {                
                var header = item.data.Name;
                //isField returns a boolean if the field is already part of the data model
                if (!isField(fields, header)) {
                    //Add a new metadata field to the data model
                    var field = { name: header, mapping: 'Metadata[' + index + '].Value' }
                    fields.push(field)

                    //Add a new metadata column
                    var column = {
                        header: header,
                        dataIndex: header,
                        sortable: true,
                        filterable: true,
                        filter: {
                            type: 'list'
                        },
                        flex: 0.2
                    }

                    defaultColumns.push(column);
                }
            });
            model.setFields(fields);

            //reload the grid after adding columns
            var gridView = Ext.ComponentQuery.query('gridpanel')[0];
            gridView.reconfigure(store, defaultColumns);      
        });

        //reload the data after creating new fields
        store.load();

I then set the columns of the grid to defaultColumns.

{
    xtype: 'grid',                    
    store: 'Projects',
    overflowX: 'auto',
    autoScroll: true,
    features: [filters],
    columns: defaultColumns
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM