ExtJS 4: Criando Menus Accordion Dinamicamente usando MVC e Associação de Models
No post de hoje vamos ver como criar um menu dinâmico usando panel com layout accordion e dentro de cada panel um tree panel com as opções.
Esse post aborda a arquitetura MVC e também associação de Models.
Criando os Models
MenuRoot
[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]Ext.define('Sencha.model.MenuRoot', {
extend: 'Ext.data.Model',
uses: [
'Sencha.model.MenuItem'
],
idProperty: 'id',
fields: [
{
name: 'title'
},
{
name: 'iconCls'
},
{
name: 'id'
}
],
hasMany: {
model: 'Sencha.model.MenuItem',
foreignKey: 'menu_id',
name: 'items'
}
});[/code]
MenuItem
[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]Ext.define('Sencha.model.MenuItem', {
extend: 'Ext.data.Model',
uses: [
'Sencha.model.MenuRoot'
],
idProperty: 'id',
fields: [
{
name: 'text'
},
{
name: 'iconCls'
},
{
name: 'className'
},
{
name: 'id'
},
{
name: 'menu_id'
}
],
belongsTo: {
model: 'Sencha.model.MenuRoot',
foreignKey: 'menu_id'
}
});[/code]
Criando a Store
Menu
[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]Ext.define('Sencha.store.Menu', {
extend: 'Ext.data.Store',
requires: [
'Sencha.model.MenuRoot'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
storeId: 'MenuStore',
model: 'Sencha.model.MenuRoot',
proxy: {
type: 'ajax',
url: 'data/menu.json',
reader: {
type: 'json',
root: 'items'
}
}
}, cfg)]);
}
});[/code]
Json Carregado - exemplo
Criando as Views
Menu
[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]Ext.define('Sencha.view.Menu', {
extend: 'Ext.panel.Panel',
alias: 'widget.menu',
height: 432,
width: 251,
layout: {
type: 'accordion'
},
iconCls: 'home',
title: 'Menu',
initComponent: function() {
var me = this;
me.callParent(arguments);
}
});[/code]
MenuItem
[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]Ext.define('Sencha.view.MenuItem', {
extend: 'Ext.tree.Panel',
alias: 'widget.menuitem',
border: 0,
autoScroll: true,
title: '',
rootVisible: false,
initComponent: function() {
var me = this;
me.callParent(arguments);
}
});[/code]
Criando Controller
Menu
[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]Ext.define('Sencha.controller.Menu', {
extend: 'Ext.app.Controller',
models: [
'MenuRoot',
'MenuItem'
],
stores: [
'Menu'
],
views: [
'Menu',
'MenuItem'
],
onPanelRender: function(abstractcomponent, options) {
this.getMenuStore().load(function(records, op, success){
var menuPanel = Ext.ComponentQuery.query('menu')[0];
Ext.each(records, function(root){
var menu = Ext.create('Sencha.view.MenuItem',{
title: root.get('title'),
iconCls: root.get('iconCls')
});
Ext.each(root.items(), function(itens){
Ext.each(itens.data.items, function(item){
menu.getRootNode().appendChild({
text: item.get('text'),
leaf: true,
iconCls: item.get('iconCls'),
id: item.get('id'),
className: item.get('className')
});
});
});
menuPanel.add(menu);
});
});
},
onTreepanelSelect: function(selModel, record, index, options) {
Ext.Msg.alert('You selected the following menu item', record.get('text'));
},
init: function(application) {
this.control({
"menu": {
render: this.onPanelRender
},
"treepanel": {
select: this.onTreepanelSelect
}
});
}
});[/code]
Projeto Completo
Download ou Fork: https://github.com/loiane/sencha-extjs4-examples-architect/tree/master/extras/dynamic_accordion_menu
Arquivos do Sencha Architect 2 inclusos.
Crédito dos Icons: http://www.famfamfam.com/lab/icons/silk/
Baseado no exemplo do fórum extjs.com.br: http://www.extjs.com.br/forum/index.php?topic=6544.0
Até a próxima! :)