问题
I need to create Twitter Bootstrap basic NavBar component in my ExtJS 4.2 application. All I want to make my component generate the following html:
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<ul class="nav">
<li class="active"><a href="#"><i class="icon1"></i> Item #1</a></li>
<li><a href="#"><i class="icon2"></i> Item #3</a></li>
<li><a href="#"><i class="icon3"></i> Item #3</a></li>
</ul>
</div>
</div>
I've created two views (NavBar and NavBarItem correspondingly):
Ext.define('My.view.layout.Navbar', {
extend: 'Ext.container.Container',
xtype: 'navbar',
cls: 'navbar navbar-inverse navbar-fixed-top',
defaultType: 'navbaritem',
initComponent: function() {
Ext.apply(this, {
items: [
{
title: 'Item #1',
icon: 'icon1',
selected: true
},
{
title: 'Item #2',
icon: 'icon2'
},
{
title: 'Item #3',
icon: 'icon3'
}
]
});
this.callParent(arguments);
}
});
Ext.define('My.view.layout.NavbarItem', {
extend: 'Ext.Component',
xtype: 'navbaritem',
autoEl: { tag: 'li' },
config: {
title: '',
icon: null,
selected: false
},
renderTpl: '<a href="#">{icon}{title}</a>',
initComponent: function() {
....
this.callParent(arguments);
}
});
I get something like this as an output:
<div class="navbar navbar-inverse navbar-fixed-top">
<li class="active"><a href="#"><i class="icon1"></i> Item #1</a></li>
<li><a href="#"><i class="icon2"></i> Item #3</a></li>
<li><a href="#"><i class="icon3"></i> Item #3</a></li>
</div>
How can I modify my NavBar view in order it could have a custom template and children components could be added to a particular element?
回答1:
You're halfway there: your child items are rendering more or less properly, but the container will require a bit of work to avoid rendering extra elements. The catch here is that for a container, the rendering process is tightly intertwined with the layout and in fact containers render from within a layout. So you will need to fudge the auto layout a bit:
Ext.define('My.view.layout.NavBar', {
extend: 'Ext.container.Container',
alias: 'widget.navbar', // Not xtype here!
defaultType: 'navbaritem',
// Let's be declarative
items: [{
title: 'Item #1',
icon: 'icon1',
selected: true
}, {
title: 'Item #2',
icon: 'icon2'
}, {
title: 'Item #3',
icon: 'icon3'
}],
renderTpl: [
'<div class="navbar-inner">',
'<ul class="nav">',
'{%this.renderChildren(out,values)%}',
'</ul>',
'</div>',
{
renderChildren: function(out, renderData) {
// We have to be careful here, as `this`
// points to the renderTpl reference!
var me = renderData.$comp.layout,
tree = me.getRenderTree();
if (tree) {
Ext.DomHelper.generateMarkup(tree, out);
}
}
}
]
});
Instantiating this container will give you approximately this output:
<div ...>
<div class="navbar-inner">
<ul class="nav" ...>
<li ...>
<a href="#">...</a>
</li>
<li ...>
<a href="#">...</a>
</li>
<li ...>
<a href="#">...</a>
</li>
</ul>
</div>
</div>
I'm simplifying here and the actual elements rendered to the DOM will get a lot of auto-generated classes, ids, and other attributes, so you will have to tweak your templates even more, but I hope you get the gist of it.
来源:https://stackoverflow.com/questions/18239250/extjs-4-how-to-wrap-children-components-of-container-in-custom-html