基本上我想要的是,使用一些可以最大化占用其父组件的组件。
因此我在Ext.window.Window
(Panel)中使用Ext.panel.Panel
(Window)组件,我可以在多行窗口中以某种方式复制它。必须使用Ext.view.View
使用Xtemplate
(DataView)呈现窗口
Window具有名为tpl
的属性,但我认为,Window 存储属性与其他组件一样,但它具有数据属性。
这是 fiddle
那么如何在Xtemplate窗口中使用Store加载数据?
另一个问题:当我尝试在窗口对象中使用initComponent()
启动组件时,它总是在控制台(chrome)中抛出错误:
Uncaught TypeError: Cannot read property 'insert' of undefined
面板
Ext.create('Ext.panel.Panel', {
id: 'panel-id',
itemId: 'panel-id',
height: 600,
width: 600,
resizable: true,
border: true,
layout: 'vbox',
renderTo: Ext.getBody()
});
模板
var tpl= new Ext.XTemplate(
'<div>My name is <b>{name}</b></div>'
);
窗口
Ext.create("Ext.window.Window", {
width: 600,
maximizable: true,
constrain: true,
resizable: false,
constrainHeader: true,
constrainTo: 'panel-id',
renderTo: 'panel-id',
autoShow: true,
initComponent: function()
{
this.tpl= tpl;
this.data= {"name":"agpt"};
this.callParent(arguments);
}
});
所以,如果我在窗口内提到initComponent()
,我完全没理解为什么窗口没有在面板中进行渲染。感谢
答案 0 :(得分:2)
考虑到这样的事情:
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
}]
});
请参阅小提琴的this fork。
一些解释......
首先,windows是浮动组件。它们不打算在面板或任何东西中呈现。它们漂浮在其余部分之上。所以你可能想要更基本的东西。
大多数组件都可以接受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
。
编辑:最大化父级面板
如果我的评论正确,您希望您的子组件在其父级内可以最大化(而不是在整个浏览器窗口中最大化)。据我所知,没有任何内置的Ext会给你这个;所以你必须自己实施这样的行为。
第一个想法可能是使用setLayout
方法在vbox
和fit
之间交换布局。不幸的是,正如文档中强调的那样:
注意:在将组件渲染到DOM之后,此方法不能用于更改布局的“类型”。
没有运气。所以你必须做一些复杂的事情。我看到它的方式,你应该给你的父面板一个card
布局,并在其中放入两个容器:一个具有框布局,另一个具有合适的布局。要“最大化”子组件,然后将其从框布局容器移动到适合容器,并将卡切换到后者。要从最大化恢复,请将子组件放回原始位置,然后将卡切换回盒子容器。
以下是一些示例代码(以及另一个fork of the fiddle):
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: []
}]
});