Sorry, this entry is only available in Português.
Iniciando uma série de posts sobre o novo Ext 4.0 não poderia começar por nada além do código mais básico do Ext, o sistema de classes. Pela primeira vez na história, a grande refatoração iniciou desde os fundamentos do framework, melhorando 100% o código anterior. As classes estão melhor estruturadas, com uma divisão mais clara entre atributos estáticos, objetos de configuração e métodos. Estão também mais fáceis de desenvolver, testar e executar. E com certeza melhores de manter.
JavaScript é uma linguagem orientada em prototipagem, sem classes. Assim, por natureza, uma das características mais marcantes da linguagem é a flexibilidade. É possível obter um mesmo resultado por diferentes maneiras, em diferentes estilos de codificação e técnicas. Essa característica, entretanto, vêm com o preço da imprevisibilidade. Sem uma estrutura unificada, código Javascript pode ser muito difícil de entender, manter e reutilizar.
Programação baseada em classes, em outro extremo, continua como o modelo mais popular de POO. Linguagens baseadas em classes geralmente requerem forte tipagem, provêm encapsulamento, e possuem padrões e convenções de código. Por geralmente fazer desenvolvedores aderirem a um grande número de princípios, o código escrito tende a ser mais previsível, extensível, e escalável ao longo do tempo. Entretanto, elas não possuem a mesma capacidade dinâmica encontrada em linguagens como Javascript.
Cada abordagem possui seus prós e contras, mas será que podemos ter os prós de ambas ao mesmo tempo, enquanto conciliamos os contras? A resposta é sim, e nós implementamos a solução no Ext JS 4.
- Ext JS Documentation, Class System
Convenção de Código
Para manter um padrão de codificação foram publicadas as convenções de código que devem ser adotadas pelos programadores Ext. Isto não torna o código mais rápido, mas com certeza o torna melhor, mais fácil de dar manutenção e de entender. Vou tentar citar as principais, uma lista completa e detalhada encontra-se no guia Class System.
Classes
Devem conter somente caracteres alfanuméricos, sendo que números devem ser evitados, a menos que pertençam a termo técnico.
Btti.util.Base64 é aceitável
As classes devem ser organizadas em pacotes, mantendo somente 1 nome para o pacote de mais alto nível. Só o pacote de mais alto nível e o nome da classe devem ser CamelCase, o restante é minúsculo
Btti.data.SQLProxy
Btti.Viewport
Acrônimos também devem seguir o padrão CamelCase
Ext.data.JsonProxy ao invés de Ext.data.JSONProxy
MyCompany.util.HtmlParser ao invés de MyCompary.parser.HTMLParser
Arquivos Fonte
O nome das classes mapeiam diretamente para o caminho aonde os arquivos são armazenados, como resultado deve existir somente 1 classe por arquivo. Exemplo:
Ext.util.Observable é armazenado em path/to/src/Ext/util/Observable.js
Btti.pedidos.Listagem é armazenado em path/to/src/Btti/pedidos/Listagem.js
aonde path/to/src é o diretório de classes da sua aplicação. Todas as classes devem estar em um único diretório e devem ser apropriadamente divididas em namespace, para melhor desenvolvimento, manutenção, e facilidades em implantações.
Métodos e Variáveis
Funcionam de forma análoga a classes, porém no padrão camelCase.
encodeUsingMd5()
getHtml() ao invés de getHTML()
var isGoodName
var base64Encoder
var xmlReader
Propriedades
Seguem o mesmo padrão de métodos e variávels, exceto quando é uma propriedade estática de uma classe, que são constantes. Estas são escritas todas em maiúsculo:
Ext.MessageBox.YES = "Yes"
Btti.Viewport.THEME = 'btti-verde'
Estrutura das Classes
A maneira antiga de declarar classes gerava códigos similares a este:
Ext.ns('Btti.grid');
Btti.grid.ListagemBase = Ext.extend(Ext.grid.GridPanel,{
/** @readonly **/
totalRegistros: 20,
/** @cfg {Boolean} usaPaginacao Indica se o grid usa ou não paginação */
usaPaginacao: true,
initComponent: function()
{
if(this.usaPaginacao)
{
this.bbar = new Ext.PagingToolbar({
store: this.store,
pageSize: this.totalRegistros
});
}
Btti.grid.ListagemBase.superclass.initComponent.call(this);
}
});
Ext.reg('btti.listagembase', Btti.grid.ListagemBase);
Este código define uma classe Btti.grid.ListagemBase que serve como facilitador na criação de grids com paginação. Basta definir usaPaginacao true ou false, para criar o toolbar. Em complemento existe uma propriedade totalRegistros que é um valor padrão somente-leitura que nenhum desenvolvedor deveria sobreescrever. Apesar de funcionar bem, existem alguns inconvenientes com este modelo
Primeiro, Btti.grid deve existir antes de associarmos ListagemBase a ele. Isso requer que usemos Ext.namespace() (ou o atalho Ext.ns()) para criar o namespace. Ainda, Ext.grid.GridPanel deve existir/estar carregado antes mesmo de iniciar este código. Mas Ext.grid.GridPanel pode ter dependências, e estas dependências possuírem outras dependências, o que nos força a carregar todo o framework em ext-all.js ao invés de somente os códigos que necessitamos. E ainda, não existe uma separação clara entre propriedades da classe que não devem ser manipuladas (como totalRegistros), e configurações do usuário (como usaPaginacao).
No Ext 4 tudo isso é resolvido, e resume-se nisto:
Ext.define('Btti.grid.ListagemBase',{
extend: 'Ext.grid.Panel',
alias: ['btti.listagembase'],
/** @readonly **/
totalRegistros: 20,
config:{
/** @cfg {Boolean} usaPaginacao Indica se o grid usa ou não paginação */
usaPaginacao: true
},
initComponent: function()
{
if(this.config.usaPaginacao)
{
this.dockedItems = this.dockedItems||[];
this.dockedItems.push({
xtype: 'pagingtoolbar',
dock: 'bottom',
itemId: 'paginacao',
store: this.store
});
}
this.callParent();
},
applyUsaPaginacao: function(usaPaginacao)
{
if(usaPaginacao === true)
{
this.addDocked({
xtype: 'pagingtoolbar',
dock: 'bottom',
itemId: 'paginacao',
store: this.store,
pageSize: this.totalRegistros
});
}
else
{
this.removeDocked(this.getDockedComponent('paginacao'));
}
}
});
O nome da classe, e também de quem ela extende, são strings. Isso evita erros caso o namespace ainda não tenha sido inicializado, ou a classe extendida não tenha sido carregada. O Ext trata de iniciar e carregar tudo, desde que a estrutura proposta nas convenções seja seguida.
Propriedades configuráveis pelo usuário (config options) agora estão reservadas em config. Além de ficar melhor estruturado, o Ext ainda cria automaticamente métodos setUsaPaginacao e getUsaPaginacao. E se algum código precisar ser executado ao alterar o valor da configuração, como no meu exemplo que é adicionar e remover o toolbar de paginação conforme a propriedade muda, pode ser implementado um método apply, como em applyUsaPaginacao
Outros detalhes que possam chamar a atenção:
-
Redundâncias foram eliminadas, como Ext.grid.GridPanel para Ext.grid.Panel, Ext.PagingToolbar para Ext.toolbar.Paging, Ext.tree.TreePanel para Ext.tree.Panel, etc…
-
Toolbars em componentes são considerados dockedItems. Eles podem ser ancorados em qualquer posição (topo, base, esquerda e direita), e podem existir vários, um adjacente ao outro.
-
Invocar o método da classe pai agora é um simples this.callParent(); ao invés de Btti.grid.ListagemBase.superclass.initComponent.call(this);.
Conclusão
Achei essas alterações as melhores da nova versão. Ficou bom demais escrever classes agora, pois tudo fica muito bem estruturado e fácil de manipular. Sem contar na conveniência de ter muito código automatizado pelo Ext.
Também achei ótimo publicar as convenções de desenvolvimento. Tenho certeza que muitos desenvolvedores possuem opiniões diferentes, e talvez contrariem as convenções. Caso vá por este caminho, tenha em mente que muitas facilidades e automatizações possam não estar disponíveis para o seu código, e suas próprias convenções.
Muitas das informações aqui publicadas foram extraídas do guia oficial Class System, publicado na documentação do Ext JS 4.0. Se vocês quiserem mais detalhes, este é o lugar para procurar.
Forte abraço, até a próxima.