view
Ext.define('KitchenSink.view.grid.ExpanderLockable', {
extend: 'Ext.grid.Panel',
xtype: 'expander-lockable',
store: 'Companies',
columns: [
{text: "Company", flex: 1, dataIndex: 'name'},
{text: "Price", formatter: 'usMoney', dataIndex: 'price'},
{text: "Change", dataIndex: 'change'},
{text: "% Change", dataIndex: 'pctChange'},
{text: "Last Updated", width: 120, formatter: 'date("m/d/Y")', dataIndex: 'lastChange'}
],
columnLines: true,
enableLocking: true,
height: 300,
//第一次接触写插件,这里是ptype,之前写features的时候里面是ftype,真直接
//一个对象或者对象数组, 组件将提供自定义功能. 一个有效的插件唯一的要求是包含一个 init 方法, 接收一个 Ext.Component 类型参数. 当组件被创建时, 如果有可用的插件, 组件将会调用每个插件的 init 方法, 并将自身的引用作为方法参数传递给它. 然后, 每个插件就可以调用方法或者响应组件上的事件, 就像需要的那样提供自己的功能.
plugins: [{
ptype: 'rowexpander',
//owbody特征是提供一个额外的横跨整个原始行tr -> td -> div图层。
//看下文的Ext.XTemplate就很好懂代码的意思了
rowBodyTpl : new Ext.XTemplate(
'<p><b>Company:</b> {company}</p>',
'<p><b>Change:</b> {change:this.formatChange}</p><br>',
'<p><b>Summary:</b> {desc}</p>',
{
formatChange: function(v){
var color = v >= 0 ? 'green' : 'red';
return '<span style="color: ' + color + ';">' + Ext.util.Format.usMoney(v) + '</span>';
}
})
}],
collapsible: true,
animCollapse: false,
title: 'Expander Rows in a Collapsible Grid with lockable columns',
iconCls: 'icon-grid',
initComponent: function() {
this.width = 750;
this.callParent();
}
});
Ext.XTemplate
这个类的用法很高级
1、自动输出数组(来自脚本娃娃翻译的Ext.js中文API,以后都简单备注为脚本娃娃)
示例数据
var data = {
name: 'Don Griffin',
title: 'Senior Technomage',
company: 'Sencha Inc.',
drinks: ['Coffee', 'Water', 'More Coffee'],
kids: [
{ name: 'Aubrey', age: 17 },
{ name: 'Joshua', age: 13 },
{ name: 'Cale', age: 10 },
{ name: 'Nikol', age: 5 },
{ name: 'Solomon', age: 0 }
]
};
标签tpl和操作符for可以用来处理提供的数据对象。
如果操作符for中值是一个数组,它将自动输出,并不断重复tpl标签内的模板块输出数组中的每一项。
只有检查通过的数据对象,才符合for所需要的规定数据对象。
然而处理一个数组,特殊的变量#提供了当前的数组的索引+1(由1开始,不是0)。
示例:
<tpl for=".">...</tpl> // 循环数组的root节点
<tpl for="foo">...</tpl> // 循环数组的foo节点
<tpl for="foo.bar">...</tpl> // 循环数组的foo.bar节点
使用标准数据
var tpl = new Ext.XTemplate(
'<p>Kids: ',
'<tpl for=".">', // 处理数据的子节点
'<p>{#}. {name}</p>', // #当前数组的索引当自动编号
'</tpl></p>'
);
tpl.overwrite(panel.body, data.kids); // 传递数据对象子节点的属性
怎样把操作符for中属性通过数据对象中成员移动到template中
var tpl = new Ext.XTemplate(
'<p>Name: {name}</p>',
'<p>Title: {title}</p>',
'<p>Company: {company}</p>',
'<p>Kids: ',
'<tpl for="kids">', // 查询数据中子节点的属性
'<p>{name}</p>',
'</tpl></p>'
);
tpl.overwrite(panel.body, data); // 传递数据对象的root节点
单一数组(Flat arrays)指的是只包含值的(不是对象),可以使用特殊变量{.}循环输出这类型的数组。这个变量代表当前数组的索引值:
var tpl = new Ext.XTemplate(
'<p>{name}\'s favorite beverages:</p>',
'<tpl for="drinks">',
'<div> - {.}</div>',
'</tpl>'
);
tpl.overwrite(panel.body, data);
通过父对象成员的parent对象,循环一个子数组
var tpl = new Ext.XTemplate(
'<p>Name: {name}</p>',
'<p>Kids: ',
'<tpl for="kids">',
'<tpl if="age > 1">',
'<p>{name}</p>',
'<p>Dad: {parent.name}</p>',
'</tpl>',
'</tpl></p>'
);
tpl.overwrite(panel.body, data);
store
Ext.define('KitchenSink.store.Companies', {
extend: 'Ext.data.ArrayStore',
alias: 'store.companies',
model: 'KitchenSink.model.Company',
data: [
[0, '3m Co', 71.72, 0.02, 0.03, '9/1 12:00am', 'Manufacturing'],
[1, 'Alcoa Inc', 29.01, 0.42, 1.47, '9/1 12:00am', 'Manufacturing'],
[2, 'Altria Group Inc', 83.81, 0.28, 0.34, '9/1 12:00am', 'Manufacturing'],
[3, 'American Express Company', 52.55, 0.01, 0.02, '9/1 12:00am', 'Finance'],
[4, 'American International Group, Inc.', 64.13, 0.31, 0.49, '9/1 12:00am', 'Services'],
[5, 'AT&T Inc.', 31.61, -0.48, -1.54, '9/1 12:00am', 'Services'],
[6, 'Boeing Co.', 75.43, 0.53, 0.71, '9/1 12:00am', 'Manufacturing'],
[7, 'Caterpillar Inc.', 67.27, 0.92, 1.39, '9/1 12:00am', 'Services'],
[8, 'Citigroup, Inc.', 49.37, 0.02, 0.04, '9/1 12:00am', 'Finance'],
[9, 'E.I. du Pont de Nemours and Company', 40.48, 0.51, 1.28, '9/1 12:00am', 'Manufacturing'],
[10, 'Exxon Mobil Corp', 68.1, -0.43, -0.64, '9/1 12:00am', 'Manufacturing'],
[11, 'General Electric Company', 34.14, -0.08, -0.23, '9/1 12:00am', 'Manufacturing'],
[12, 'General Motors Corporation', 30.27, 1.09, 3.74, '9/1 12:00am', 'Automotive'],
[13, 'Hewlett-Packard Co.', 36.53, -0.03, -0.08, '9/1 12:00am', 'Computer'],
[14, 'Honeywell Intl Inc', 38.77, 0.05, 0.13, '9/1 12:00am', 'Manufacturing'],
[15, 'Intel Corporation', 19.88, 0.31, 1.58, '9/1 12:00am', 'Computer'],
[16, 'International Business Machines', 81.41, 0.44, 0.54, '9/1 12:00am', 'Computer'],
[17, 'Johnson & Johnson', 64.72, 0.06, 0.09, '9/1 12:00am', 'Medical'],
[18, 'JP Morgan & Chase & Co', 45.73, 0.07, 0.15, '9/1 12:00am', 'Finance'],
[19, 'McDonald\'s Corporation', 36.76, 0.86, 2.40, '9/1 12:00am', 'Food'],
[20, 'Merck & Co., Inc.', 40.96, 0.41, 1.01, '9/1 12:00am', 'Medical'],
[21, 'Microsoft Corporation', 25.84, 0.14, 0.54, '9/1 12:00am', 'Computer'],
[22, 'Pfizer Inc', 27.96, 0.4, 1.45, '9/1 12:00am', 'Medical'],
[23, 'The Coca-Cola Company', 45.07, 0.26, 0.58, '9/1 12:00am', 'Food'],
[24, 'The Home Depot, Inc.', 34.64, 0.35, 1.02, '9/1 12:00am', 'Retail'],
[25, 'The Procter & Gamble Company', 61.91, 0.01, 0.02, '9/1 12:00am', 'Manufacturing'],
[26, 'United Technologies Corporation', 63.26, 0.55, 0.88, '9/1 12:00am', 'Computer'],
[27, 'Verizon Communications', 35.57, 0.39, 1.11, '9/1 12:00am', 'Services'],
[28, 'Wal-Mart Stores, Inc.', 45.45, 0.73, 1.63, '9/1 12:00am', 'Retail'],
[29, 'Walt Disney Company (The) (Holding Company)', 29.89, 0.24, 0.81, '9/1 12:00am', 'Services']
]
}, function(cls) {
var data = cls.prototype.config.data;
for(var i = 0; i < data.length; i++){
data[i].push('Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed metus nibh, sodales a, porta at, vulputate eget, dui. Pellentesque ut nisl. ');
}
});
model
Ext.define('KitchenSink.model.Company', {
extend: 'KitchenSink.model.Base',
fields: [
{name: 'name'},
{name: 'price', type: 'float'},
{name: 'change', type: 'float'},
{name: 'pctChange', type: 'float'},
{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'},
{name: 'industry'},
{name: 'desc'},
// Trend begins with the cerrent price. Changes get pushed onto the end
{
name: 'trend',
convert: function(value, record) {
// Record creation call with no trend there: start with current price
if (value === null) {
return [record.get('price')];
}
return Ext.isArray(value) ? value : [ value ];
}
},
// Rating dependent upon performance 0 = best, 2 = worst
{
name: 'rating',
type: 'int',
convert: function(value, record) {
var pct = record.get('pctChange');
if (pct < 0)
return 2;
if (pct < 1)
return 1;
return 0;
}
}
],
// Override to keep the last 10 prices in the trend field
set: function(fieldName, value) {
if (fieldName === 'price') {
this.callParent([{
price: value,
trend: this.addToTrend(fieldName.price)
}]);
}
else {
if (typeof fieldName !== 'string' && 'price' in fieldName) {
fieldName.trend = this.addToTrend(fieldName.price);
}
this.callParent(arguments);
}
},
// Override to keep the last 10 prices in the trend field
addToTrend: function(value) {
var trend = this.data.trend.concat(value);
if (trend.length > 10) {
Ext.Array.splice(trend, 0, trend.length - 10);
}
return trend;
}
});