使用Ext.create在ExtJS 4 GridPanel列中呈现动态组件 [英] Render dynamic components in ExtJS 4 GridPanel Column with Ext.create

查看:103
本文介绍了使用Ext.create在ExtJS 4 GridPanel列中呈现动态组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ExtJS(4.0.7)GridPanel,我正在从一个商店填充。我在GridPanel列中显示的值需要根据记录中的数据类型有不同的视图。



最终目标是记录double 或整数值为记录的类型属性提供了一个滑块给用户他们可以调整,一种类型的字符串只是渲染一些只读文本。



我已经创建了一个自定义列来执行此操作。它会检查渲染器中的类型并确定要呈现的内容。



我已经使用下面的代码对string工作正常,但是我如何动态地努力在列中创建并呈现更复杂的滑块控件。



这个简化的例子只是试图渲染一个面板有一个日期控制,就像我可以得到那样,我可以弄清楚其余的滑块的东西。

  Ext .define('MyApp.view.MyColumn',{
extends:'Ext.grid.column.Column',
alias:['widget.mycolumn'],

stringTemplate:new Ext.XTemplate('code to render {name} for string items'),

构造函数:function(cfg){
var me = this;
me。 callParent(arguments);

me.renderer = function(value,p,record){
var data = Ext.apply({},record.data,record.getAssociatedData()) ;

if(data.type ==string) {
return me.renderStringFilter(data);
} else if(data.type ==double|| data.type ==integer){
return me.renderNumericFilter(data);
} else {
log(Unknown data.type,data);

};
},

renderStringFilter:function(data){
//这个工作很好,做我想要的
return this.stringTemplate.apply(data);
},

renderNumericFilter:function(data){

// *****如何获取一个组件创建来渲染
// *****在它在gridpanel中的适当位置?
//我真正想要的是一个具有完整行为的滑块
//这是一个占位符,只是想创建一些东西来渲染

var filterPanel = Ext。 create('Ext.panel.Panel',{
title:'Filters',
items:[{
xtype:'datefield',
fieldLabel:'date'
}],
renderTo:Ext.getBody()//这不工作
});
return filterPanel.html; //这不工作
}
});

我的问题真的是,我如何 Ext.create 一个组件,并将它渲染成一个列在gridpanel?

解决方案

有几种方法我有看到这完成了。由于网格列不是Ext容器,因此其他容器组件可以以任何配置的方式将Ext组件作为子项。需要将网格渲染逻辑添加到单元格中。



此解决方案修改您的自定义列渲染,以便在渲染的TD标签上放置一个特殊的css类。网格视图准备就绪后,遍历记录,找到适合特殊列的自定义类。一个滑块被渲染到找到的每一列。



下面的代码是Sencha示例中提供的ext js数组网格示例的修改版本。该修改会在自定义列渲染器中进行混合,并将滑块的后置网格渲染到TD元素。



此示例仅包含对Sencha示例的足够修改,以显示实现思想。它没有分离的视图和控制器逻辑。



这是从:
http://docs.sencha.com/ext-js/4-0/#!/example/grid/array -grid.html

  Ext.require([
'Ext.grid。*',
'Ext.data。*',
'Ext.util。*',
'Ext.data.Model'
]);


Ext.onReady(function(){

//存储商店的静态数据样本
Ext.define('Company',{
extends:'Ext.data.Model',
fields:['name','price','change','pctChange','lastUpdated','type']
}) ;

var myData = [
['3m Co',71.72,2,0.03,'9/1/2011','integer'],
['Alcoa Inc ',29.01,4,1.47,'9/1/2011','string'],
['Altria Group Inc',83.81,6,0.34,'9/1/2011','string'] ,
['American Express Company',52.55,8,0.02,'9/1/2011','string'],
['American International Group,Inc.',64.13,2,0.49 ,'9/1/2011','integer'],
['AT& T Inc.',31.61,4,-1.54,'9/1/2011','integer'],
['波音公司' 75.43,6,0.71,'9/1/2011','string'],
['Caterpillar Inc.',67.27,8,1.39,'9/1/2011','integer'],
['Citigroup,Inc.',49.37,1,0.04,'9/1/2011','integer'],
['EI du Pont de Nemours and Company',40.48,3,1.28,'9/1/2011','integer'],
['Exxon Mobil Corp',68.1,0,-0.64,'9/1 / 2011','integer'],
['通用电气公司',34.14,7,-0.23,'9/1/2011','整数']
];

//创建数据存储
var store = Ext.create('Ext.data.ArrayStore',{
model:'Company',
data: myData
});

//现有模板
stringTemplate = new Ext.XTemplate('代码为字符串项目渲染{name});

//自定义列渲染器
specialRender = function(value,metadata,record){
var data;

data = Ext.apply({},record.data,record.getAssociatedData());

if(data.type ==string){
return stringTemplate.apply(data);;
} else if(data.type ==double|| data.type ==integer){
//添加css选择器到td html类属性,我们可以在网格后使用它准备渲染滑块
metadata.tdCls = metadata.tdCls +'slider-target';
return'';
} else {
return(Unknown data.type);

}
};

//创建网格
grid = Ext.create('Ext.grid.Panel',{
rowsWithSliders:{},
store:store,
stateful:true,
stateId:'stateGrid',
columns:[
{
text:'Company',
flex:1,
sortable:false,
dataIndex:'name'
},
{
text:'Price',
width:75,
sortable:true ,
renderer:'usMoney',
dataIndex:'price'
},
{
text:'Change',
width:75,
可排序:true,
dataIndex:'change',
renderer:specialRender,
width:200
},
{
文本:'%Change',
width:75,
sortable:true,
dataIndex:'pctChange'
},
{
text:'最后更新'
width:85,
sortable:true,
renderer:Ext.util.Format.dateRenderer('m / d / Y'),
dataIndex:'最后更新'
}
],
height:350,
width:600,
title:'Irm Grid Example',
renderTo:'grid-示例',
viewConfig:{
stripeRows:true
}
});

/ **
*当网格视图准备就绪时,此方法将找到滑块列并将滑块呈现给他们
* /
onGridViewReady = function(){
var recordIdx,
colVal,
colEl;

for(recordIdx = 0; recordIdx< grid.store.getCount(); recordIdx ++){
record = grid.store.getAt(recordIdx);
sliderHolder = Ext.DomQuery.select('。slider-target',grid.view.getNode(recordIdx));
if(sliderHolder.length){
colEl = sliderHolder [0];

//删除由网格模板生成的div - 替代方法是在col
中使用一个新模板colEl.innerHTML ='';

//从记录和列中获取要用于滑块的值
colVal = record.get('change');

//渲染滑块 - 传入完整记录,以备变更处理程序可能需要记录数据
renderNumericFilter(colEl,colVal,record)
}
}

}

//当网格视图准备就绪时,将滑块渲染为
grid.on('viewready',onGridViewReady,this);

//修改现有方法,但从自定义列中删除
renderNumericFilter = function(el,val,record){

var filterPanel = Ext.widget('滑块',{
width:200,
value:val,
record:record,
minValue:0,
maxValue:10,
renderTo: el
});

}

});


I've got an ExtJS (4.0.7) GridPanel that I'm populating from a store. The values that I display in the GridPanel's column need to have a different view depending on the type of data that's in the record.

The ultimate goal is that records with "double" or "integer" value for the record's type property present a slider to the user that they can adjust, and a type of "string" just renders some read-only text.

I've created a custom Column to do this. It inspects the type in the renderer and determines what to render.

I've got the "string" working fine with the code below, but struggling with how I can dynamically create and render the more complicated slider control in the column.

This simplified example is just trying to render a Panel with a date control in it as if I can get that going, I can figure out the rest of the slider stuff.

Ext.define('MyApp.view.MyColumn', {
    extend: 'Ext.grid.column.Column',
    alias: ['widget.mycolumn'],

    stringTemplate: new Ext.XTemplate('code to render {name} for string items'),

    constructor: function(cfg){
        var me = this;
        me.callParent(arguments);

        me.renderer = function(value, p, record) {
            var data = Ext.apply({}, record.data, record.getAssociatedData());

            if (data.type == "string") {
                return me.renderStringFilter(data);
            } else if (data.type == "double" || data.type == "integer") {
                return me.renderNumericFilter(data);
            } else {
                log("Unknown data.type", data);

        };
    },

    renderStringFilter: function(data) {
        // this works great and does what I want
        return this.stringTemplate.apply(data);
    },

    renderNumericFilter: function(data) {

        // ***** How do I get a component I "create" to render 
        // ***** in it's appropriate position in the gridpanel?
        // what I really want here is a slider with full behavior
        // this is a placeholder for just trying to "create" something to render

        var filterPanel = Ext.create('Ext.panel.Panel', {
            title: 'Filters',
            items: [{
                xtype: 'datefield',
                fieldLabel: 'date'
            }],
            renderTo: Ext.getBody() // this doesn't work
        });
        return filterPanel.html;  // this doesn't work
    }
});

My problem really is, how can I Ext.create a component, and have it render into a column in the gridpanel?

解决方案

There are a few ways that I have seen this accomplished. Since the grid column is not an Ext container it can not have Ext components as children as part of any configuration the way other container components can. Post grid-rendering logic is required to add Ext components to cells.

This solution modifies your custom column render so that it puts a special css class on the rendered TD tag. After the grid view is ready, the records are traversed and the custom class is found for appropriate special columns. A slider is rendered to each column found.

The code below is a modified version of the ext js array grid example provided in the Sencha examples. The modification mixes in the custom column renderer and the post grid rendering of sliders to TD elements.

This example only includes enough modification of the Sencha example to show the implementation ideas. It lacks separated view and controller logic.

This is modified from: http://docs.sencha.com/ext-js/4-0/#!/example/grid/array-grid.html

Ext.require([
    'Ext.grid.*',
    'Ext.data.*',
    'Ext.util.*',
    'Ext.data.Model'
]);


Ext.onReady(function() {

    // sample static data for the store
    Ext.define('Company', {
        extend: 'Ext.data.Model',
        fields: ['name', 'price', 'change', 'pctChange', 'lastUpdated', 'type']
    }); 

    var myData = [
        ['3m Co',                               71.72, 2,  0.03,  '9/1/2011', 'integer'],
        ['Alcoa Inc',                           29.01, 4,  1.47,  '9/1/2011', 'string'],
        ['Altria Group Inc',                    83.81, 6,  0.34,  '9/1/2011', 'string'],
        ['American Express Company',            52.55, 8,  0.02,  '9/1/2011', 'string'],
        ['American International Group, Inc.',  64.13, 2,  0.49,  '9/1/2011', 'integer'],
        ['AT&T Inc.',                           31.61, 4, -1.54, '9/1/2011', 'integer'],
        ['Boeing Co.',                          75.43, 6,  0.71,  '9/1/2011', 'string'],
        ['Caterpillar Inc.',                    67.27, 8,  1.39,  '9/1/2011', 'integer'],
        ['Citigroup, Inc.',                     49.37, 1,  0.04,  '9/1/2011', 'integer'],
        ['E.I. du Pont de Nemours and Company', 40.48, 3,  1.28,  '9/1/2011', 'integer'],
        ['Exxon Mobil Corp',                    68.1,  0, -0.64, '9/1/2011', 'integer'],
        ['General Electric Company',            34.14, 7, -0.23, '9/1/2011', 'integer']
    ];

    // create the data store
    var store = Ext.create('Ext.data.ArrayStore', {
        model: 'Company',
        data: myData
    });

    // existing template
    stringTemplate = new Ext.XTemplate('code to render {name} for string items');

    // custom column renderer
    specialRender = function(value, metadata, record) {
        var data;

        data = Ext.apply({}, record.data, record.getAssociatedData());

        if (data.type == "string") {
            return stringTemplate.apply(data);;
        } else if (data.type == "double" || data.type == "integer") {
            // add a css selector to the td html class attribute we can use it after grid is ready to render the slider
            metadata.tdCls = metadata.tdCls + 'slider-target';
            return '';
        } else {
            return("Unknown data.type");

        }
    };

    // create the Grid
    grid = Ext.create('Ext.grid.Panel', {
        rowsWithSliders: {},
        store: store,
        stateful: true,
        stateId: 'stateGrid',
        columns: [
            {
                text     : 'Company',
                flex     : 1,
                sortable : false,
                dataIndex: 'name'
            },
            {
                text     : 'Price',
                width    : 75,
                sortable : true,
                renderer : 'usMoney',
                dataIndex: 'price'
            },
            {
                text     : 'Change',
                width    : 75,
                sortable : true,
                dataIndex: 'change',
                renderer: specialRender,
                width: 200
            },
            {
                text     : '% Change',
                width    : 75,
                sortable : true,
                dataIndex: 'pctChange'
            },
            {
                text     : 'Last Updated',
                width    : 85,
                sortable : true,
                renderer : Ext.util.Format.dateRenderer('m/d/Y'),
                dataIndex: 'lastUpdated'
            }
        ],
        height: 350,
        width: 600,
        title: 'Irm Grid Example',
        renderTo: 'grid-example',
        viewConfig: {
            stripeRows: true
        }
    });

    /**
     * when the grid view is ready this method will find slider columns and render the slider to them
     */
    onGridViewReady = function() {
        var recordIdx,
            colVal,
            colEl;

        for (recordIdx = 0; recordIdx < grid.store.getCount(); recordIdx++ ) {
            record = grid.store.getAt(recordIdx);
            sliderHolder = Ext.DomQuery.select('.slider-target', grid.view.getNode(recordIdx)); 
            if (sliderHolder.length) {
                colEl = sliderHolder[0];

                // remove div generated by grid template - alternative is to use a new template in the col
                colEl.innerHTML = '';

                // get the value to be used in the slider from the record and column
                colVal = record.get('change');

                // render the slider - pass in the full record in case record data may be needed by change handlers
                renderNumericFilter(colEl, colVal, record)
            }
        }

    }

    // when the grids view is ready, render sliders to it
    grid.on('viewready', onGridViewReady, this);

    // modification of existing method but removed from custom column 
    renderNumericFilter = function(el, val, record) {

        var filterPanel = Ext.widget('slider', {
            width: 200,
            value: val,
            record: record,
            minValue: 0,
            maxValue: 10,
            renderTo: el
        });

    }

});

这篇关于使用Ext.create在ExtJS 4 GridPanel列中呈现动态组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆