我正在尝试在包含20多个单元格的网格中展开一行。当扩展器内没有数据时,扩展器会正确扩展和折叠。但每当我在扩展器中输入任何值/数据时,存储就会更新并且扩展器会崩溃。如果单击网格行,折叠的展开器将不会再次展开。
Ext.define('RowExpanderWithComponents', {
extend : 'Ext.grid.plugin.RowExpander',
alias: 'plugin.rowexpanderwithcomponents',
rowBodyTpl : new Ext.XTemplate(
'<div id="display-row-{id}"> </div>'
),
rowBodyCompTemplate: null,
expandOnClick: true,
hideExpandColumn: true,
enableTextSelection: true,
init : function(grid){
var me = this,
view;
me.callParent(arguments);
view = me.view = grid.getView();
grid.addCls('rowexpanderwithcomponents');
if(me.hideExpandColumn){
grid.headerCt.query('gridcolumn')[0].hidden = true;
}
if(me.enableTextSelection){
view.enableTextSelection = true;
}
view.on('expandbody', function(rowNode, record, expandRow, eOpts){
var recId = record.getId();
if(!recId){
Ext.Error.raise('grid-column-error');
}
var cont = this.getRowComponent(recId);
if(cont){
return;
}
var row = 'display-row-' + recId;
clonedRowTemplate = JSON.parse(JSON.stringify(me.rowBodyCompTemplate));
var parentCont = Ext.create(Ext.container.Container,{
height: '100%',
width: '100%',
itemId: grid.getId() + '-parentRowExpCont-' + recId,
items:[
me.replaceObjValues(clonedRowTemplate, record)
]
});
parentCont.render(row);
var rowEl = parentCont.getEl().parent('.x-grid-rowbody');
rowEl.swallowEvent(['mouseenter', 'click', 'mouseover', 'mousedown', 'dblclick', 'cellclick', 'itemmouseenter', 'itemmouseleave', 'onRowFocus', 'mouseleave']);
});
view.getRowComponent = me.getRowComponent;
grid.getRowComponent = me.getRowComponent;
grid.addToRowComponent = me.addToRowComponent;
grid.addToRowComponent = me.addToRowComponent;
},
getRowComponent: function(recId){
return Ext.ComponentQuery.query('#' + this.up('grid').getId() + '-parentRowExpCont-' + recId)[0];
},
removeAllFromRowComponent: function(recId){
var rowCont = this.getRowComponent(recId);
rowCont.removeAll();
},
addToRowComponent: function(recId, items){
var rowCont = this.getRowComponent(recId);
rowCont.add(items);
},
bindView: function(view) {
if (this.expandOnClick) {
view.on('itemclick', this.onItemClick, this);
}
this.callParent(arguments);
},
onItemClick: function(view, record, row, rowIdx, e,colIdx) {
this.toggleRow(rowIdx, record);
},
rowExpanded: function(expander, record, body, rowIndex) {
var key = this.getRecordKey(record);
var status = {
rendered: true, expanded: true
}; this.recordStatus[key] = status;
},
rowCollapsed: function(expander, record, body, rowIndex) {
var key = this.getRecordKey(record);
var status = { rendered: true, expanded: false };
this.recordStatus[key] = status;
},
onBeforeRefresh: function(view) {
var store = this.grid.getStore(), n, record; this.storedHtml = {};
for (n = 0; n < store.data.items.length; n++) {
record = store.getAt(n); this.saveRowHtml(view, n, record);
}
},
saveRowHtml: function(view, index, record) {
var key = this.getRecordKey(record);
var rowIndex = null,
found = false;
for (rowIndex in this.recordKeyAtRow) {
if (this.recordKeyAtRow[rowIndex] == key) {
found = true
break;
}
}
if (found) {
var row = view.getRow(rowIndex);
var body = Ext.DomQuery.selectNode('div.x-grid3-row-body', row);
this.storedHtml[key] = body.innerHTML;
}
},
onRefresh: function(view) {
var store = this.grid.getStore(), n, row, record;
for (n = 0; n < store.data.items.length; n++) {
row = view.getRow(n);
if (row) {
record = store.getAt(n);
this.restoreRowHtml(view, n, record);
}
}
},
restoreRowHtml: function(view, index, record) {
var key = this.getRecordKey(record);
var storedBody = this.storedHtml[key];
if (!Ext.isEmpty(storedBody)) {
var row = view.getRow(index);
var body = Ext.DomQuery.selectNode('div.x-grid3-row-body', row);
while (body.hasChildNodes()) {
body.removeChild(body.lastChild);
}
var status = this.recordStatus[key];
if (!status) {
//the row has not been touched.
body.innerHTML = this.tpl.html; this.collapseRow(row);
} else {
body.innerHTML = storedBody;
if (status.expanded) this.expandRow(row);
else this.collapseRow(row);
}
}
this.markRow(view, index, record);
},
markRow: function(view, index, record) {
var key; var row = view.getRow(index);
if (row) {
key = this.getRecordKey(record);
this.recordKeyAtRow[index] = key;
}
},
markRows: function() {
var view = this.grid.getView(),
store = this.grid.getStore(), record, n;
this.recordKeyAtRow = {};
for (n = 0; n < store.data.items.length; n++) {
record = store.getAt(n);
this.markRow(view, n, record);
}
},
replaceObjValues: function( obj, record ){
for( var all in obj )
{
if( typeof obj[all] === "string" && obj[all].match(/{{(.*)}}/) ){
obj[all] = record.get(obj[all].match(/{{(.*)}}/)[1]);
}
if( typeof obj[all] === "object" && obj[all]!== null ){
this.replaceObjValues( obj[all], record );
}
}
return obj;
}
rowexpander的插件。
* myform是具有文本字段,按钮,组合框等的表单。
{
ptype: 'rowexpanderwithcomponents',
pluginId: 'Expander',
rowBodyCompTemplate: {
xtype: 'container',
items: [{
xtype: 'myform',
border: false
}],
},
}