鉴于这样的事情:
var store = new Ext.data.Store({
fields: {name: 'name', type:'string'},
data: [
{name: "Foo"},
{name: "bar"}
]
});
您似乎正在尝试实现类似的目标:
var items = [];
store.each(function(record) {
items.push({
xtype: 'component'
,tpl: "<div>My name is <b>{name}</b></div>"
,data: record
});
});
var panel = new Ext.panel.Panel({
renderTo: Ext.getBody(),
title: "Panel with components",
height: 200,
width: 600,
resizable: true,
border: true,
layout: 'vbox',
items: items
});
或者那个:
var panel2 = new Ext.panel.Panel({
renderTo: Ext.getBody(),
title: "Panel with template",
height: 200,
width: 600,
resizable: true,
border: true,
layout: 'fit',
items: [{
xtype: 'dataview',
tpl: "<tpl for='.'><div class=\"item\">My name is <b>{name}</b></div></tpl>",
itemSelector: 'div.item',
store: store
}]
});
看看你的小提琴的这个叉子。
一些解释...
首先,窗口是浮动组件。它们不打算在面板或任何东西中呈现。它们漂浮在其余部分之上。所以你可能想要一些更基本的东西。
如文档中所述,大多数组件都可以接受tpl
将与其耦合的配置选项。data
要使用它,您可以选择最基本的Ext.Component
,或者使用更花哨的东西Ext.panel.Panel
,例如,如果您想要一个标题、可折叠的东西等。这就是我在第一个面板中使用的策略。
除了“基本”组件之外,您还Ext.view.View
可以使用模板,但这次与商店耦合。在这种情况下,您很可能希望在您的模板(<tpl for=".">
部分)中有一个循环来为每条记录呈现一些内容。
最后,关于您的initComponent
错误,这是因为this.callParent
仅对已通过 Ext 的类管理器传递的方法起作用。在您的代码中,您只是用自定义函数替换类方法,Ext 不知道如何将其链接到其父级,因此范围将不正确,因此您将在某处得到随机错误, 像你所做地。什么会起作用......
要么定义一个自定义类:
Ext.define('My.Window', {
extend: 'Ext.window.Window'
// ...
initComponent: function() {
this.tpl= view;
this.data= {"name":"agpt"};
this.callParent(arguments);
}
});
var win = new My.Window( ... );
或用于Ext.override
覆盖实例的方法(同时让 Ext 连接的方法callParent
正常工作):
var win = new Ext.Window( ... );
Ext.override(win, {
initComponent: function() {
this.tpl= view;
this.data= {"name":"agpt"};
this.callParent(arguments);
}
});
呃……事实上,第二种方式是行不通的,因为initComponent
已经在new Ext.Window( ... )
.
另一种选择是不依赖callParent
自己进行接线:
Ext.create('Ext.window.Window', {
// ...
initComponent: function() {
this.tpl= view;
this.data= {"name":"agpt"};
//this.callParent(arguments);
Ext.window.Window.prototype.initComponent.apply(this, arguments);
}
});
顺便说一句,我建议不要使用Ext.create
,而是使用new
关键字。它使缺失requires
在开发模式下立即可见。
编辑:Maximizable-in-parent Panel
如果我的评论正确,您希望您的子组件在其父组件中最大化(而不是在整个浏览器窗口中最大化)。据我所知,没有任何内置的 Ext 可以为您提供。所以你必须自己实现这样的行为。
第一个想法可能是在方法vbox
之间交换布局。不幸的是,正如文档中所强调的:fit
setLayout
注意:在组件渲染到 DOM 后,此方法不能用于更改布局的“类型”。
没运气。所以你必须做一些复杂的事情。在我看来,你应该给你的父面板一个card
布局,并在其中放置两个容器:一个是盒子布局,另一个是适合布局。为了“最大化”一个子组件,你可以将它从盒子布局容器移动到 fit 容器,并将卡片切换到后者。要从最大化恢复,您将子组件放回原来的位置,然后将卡片切换回盒子容器。
这是一些示例代码(以及小提琴的另一个分支):
var store = new Ext.data.Store({
fields: {name: 'name', type:'string'},
data: [
{name: "Foo"},
{name: "bar"}
]
});
var items = [];
store.each(function(record) {
items.push({
xtype: 'panel'
,tpl: "<div>My name is <b>{name}</b></div>"
,data: record
,tools: [{
type: 'maximize'
,handler: function(t) {
this.disable();
this.up().down('tool[type=restore]').enable();
var rootPanel = this.up('#rootPanel'),
fitCt = rootPanel.down('#fitCt'),
panel = this.up('panel');
panel.lastIndex = panel.ownerCt.items.indexOf(panel);
fitCt.add(panel);
rootPanel.getLayout().setActiveItem(fitCt);
}
},{
type: 'restore'
,disabled: true
,handler: function() {
this.disable();
this.up().down('tool[type=maximize]').enable();
var rootPanel = this.up('#rootPanel'),
listCt = rootPanel.down('#listCt'),
panel = this.up('panel');
listCt.insert(panel.lastIndex, panel);
rootPanel.getLayout().setActiveItem(listCt);
}
}]
});
});
var panel = new Ext.panel.Panel({
renderTo: Ext.getBody(),
title: "Panel with components",
itemId: 'rootPanel',
height: 200,
width: 600,
resizable: true,
border: true,
layout: 'card',
items: [{
xtype: 'container',
itemId: 'listCt',
layout: {
type: 'vbox',
align: 'stretch'
},
defaults: {
margin: 5
},
items: items
},{
xtype: 'container',
itemId: 'fitCt',
layout: 'fit',
items: []
}]
});