| Summary: Este tutorial ajuda você a escrever uma grande aplicação em ExtJS. |
| Author: Jozef Sakalos |
| Published: April 12, 2008 |
| Ext Version: 2.0+ |
Languages: English Русский
|
Contents |
Eu decidi escrever este artigo para todos os usuários de Ext 2.x que já "saíram das fraldas" no que se refere a criar uma página HTML com script incorporado criando uma janela ou um formulário simples, para quem já decidiu que Ext é o caminho; e para aqueles que estão passando dificuldade com arquivos muito grandes para pesquisar e tem a sensação de que suas aplicações necessitam de uma estrutura.
O número de abordagens de um problema e o número de soluções para isso é igual ao número de pessoas que estão dispostas a lidar com ele. A maneira que descrevo no texto a seguir não é o único caminho, e eu não quero dizer que uma aplicação deva ser escrita no meu caminho ou ela não será boa. Nada disto.
What I do want to say is that this approach is workable, neatly structured, easily maintainable --- simply stated: It works!
O que eu quero dizer é que esta abordagem é viável, facilmente estruturável e de fácil manutenção: Ela funciona!
Se você tem um Viewport com BorderLayout, um Grid e um Form, tudo em um arquivo, isto certamente não é uma grande aplicação, certo? Se você tem dezenas de Windows com um Grid, Form ou Border layout no mesmo, em dezenas de arquivos, isto certamente é uma grande aplicação, certo?
(Alemães têm uma bela palavra:Jein que é combinação de Ja= Sim e Nein = Não.)
A resposta a ambas as afirmações acima é Jein. Quando é que a aplicação se torna muito grande, então? A resposta é simples: Ela se torna grande, quando você sente que é grande. É o ponto em que começa a ter dificuldades para orientar-se em um número de arquivos ou se tiver problemas para encontrar um código ou bloco específico em um arquivo, quando você deixa de compreender as relações dos componentes, etc, estou escrevendo você aqui, mas imagino quando um programador menos experiente começa a ter este sentimento.
Nós podemos seguramente afirmar que cada aplicação é grande assim como também uma aplicação pequena merece ser bem escrita e poderá, provavelmente, se tornar realmente grande quando nós começamos a adicionar novas funcionalidades, escrever novas linhas de código, novo CSS regras, etc.
O melhor e mais seguro estado da mente no início de uma nova aplicação é o seguinte: eu estou começando a grande aplicação!
Arquivos e diretórios são o que precisamos organizar primeiro. Há sempre um diretório DocumentRoot configurado no Apache ou outro servidor HTTP, para os subdiretórios vou descrever mais tarde o que é relativo a eles.
Estrutura de diretórios recomentada:
./css (link opcional) ./ext (link) ./img (link) ./js index.html
Linkna estrutura acima significa um soft link apontando para um verdadeir diretório onde os arquivos são armazenados. A vantagem é que quando você, por exemplo, baixar uma nova versão para o verdadeiro diretório Ext, então você só precisa mudar o link, sem mudar uma linha sequer na sua aplicação. Assim, você pode testar se tudo funciona também com esta nova versão . Se sim, mantê-la como ela é; se não, basta alterar o link para voltar.
Um arquivo index.html mínimo contém:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <link rel="stylesheet" type="text/css" href="./ext/resources/css/ext-all.css"> <link rel="stylesheet" type="text/css" href="./css/application.css"> <script type="text/javascript" src="./ext/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="./ext/ext-all-debug.js"></script> <script type="text/javascript" src="./js/application.js"></script> <title>A Big Application</title> </head> <body></body> </html>
Embora você possa fazer como no arquivo acima eu recomendaria adicionar um cabeçalho descritivo, não apenas nesse arquivo, mas em todos os arquivos que você criar. Também um marcador "Fim de arquivo" tem o seu valor. Veja File Patterns para o exemplo destes tipos de cabeçalhos.
Nós precisamos de um arquivo onde a função onReady() será colocada; este arquivo chama-se application.js. Este é o seu conteúdo mínimo:
/** * An Application * * @author Ing. Jozef Sakáloš * @copyright (c) 2008, by Ing. Jozef Sakáloš * @date 2. April 2008 * @version $Id$ * * @license application.js is licensed under the terms of the Open Source * LGPL 3.0 license. Commercial use is permitted to the extent that the * code/component(s) do NOT become part of another Open Source or Commercially * licensed development library or toolkit without explicit permission. * * License details: http://www.gnu.org/licenses/lgpl.html */ /*global Ext, Application */ Ext.BLANK_IMAGE_URL = './ext/resources/images/default/s.gif'; Ext.ns('Application'); // application main entry point Ext.onReady(function() { Ext.QuickTips.init(); // code here }); // eo function onReady // eof
Seu cabeçalho e rodapé pode variar, mas certamente necessita configurar Ext.BLANK_IMAGE_URL para apontar para seu servidor. Este é o caminho para uma imagem transparente de 1x1px transparente que é usada pelo Ext como uma imagem placeholder, e se ele aponta para uma localização inválida podem acontecer diversos problemas de renderização, como a falta imagens, ícones outros similares.
Talvez você também precise criar uma variável global para a sua aplicação (neste caso é Application).
O que você precisa saber é que Ext.onReady(), é o principal ponto de entrada da sua aplicação - o lugar onde você vai escrever o seu código.
Você vai colocar seu estilo CSS, se houver, neste arquivo. Se você só precisa de poucas regras, pode parecer desnecessário criar um arquivo separado para elas, e você pensa que é uma melhor idéia colocá-los em uma tag <style> no cabeçalho da página.
O inverso é verdadeiro, lembre-se que você está escrevendo uma grande aplicação, assim tudo tem de ter o seu lugar. Se você colocar estilos no cabeçalho da página mais cedo ou mais tarde você vai ter de resolver alguns problemas e você poderá não saber mais onde estão os estilos.
O que normalmente fazemos quando temos todos os fundamentos (teoria), como temos neste momento? Vamos começar por escrever o código. Então nos sentamos e começamos a escrever:
var vp = new Ext.Viewport({
layout:'border'
,items:[
new Ext.grid.GridPanel({
store:new Ext.data.Store({
proxy:new Ext.data.HttpProxy({ ...
Espere um minuto. Desta forma, teremos 10.000 linhas em nosso application.js</ tt> muito em breve e é isso que queremos evitar. Obviamente, está faltando algum passo, se vamos criar um grande arquivo porque não fazemos isso em <tt>index.html em primeiro lugar?
Mesmo o mais complexo conjunto é constituído de pequenos sistemas que são constituídos por pequenas peças, que consistem de alguns elementos. A sua grande aplicação a ser escrita não é uma exceção. Agora é o momento para identificar as peças, componentes e relacionamentos entre eles.
Então, sente-se, pense sobre isso, desenhe um esboço, faça uma lista, qualquer que seja, mas o resultado deve corresponder ao que você sabe ou imagina sobre os componentes - pelo menos os mais importantes - a sua aplicação irá ter.
Agora que você fez uma análise da sua aplicação e identificou os seus componentes, você pode começar a escrever. Mas como?
A melhor abordagem é a escrever classes e extensões para os componentes Ext que têm opções de configuração, caso contrário, passe a configuração objeto, built-in. Eu chamo essa extensão classes pré-configuradas, uma vez que muito raramente adiciona funcionalidade à base Ext, mas o principal objetivo de tê-las é colocá-las configuradas. Por exemplo, para ter um Grid "Personal" com um específico column model, store, sorting options, editors, etc
Se fizéssemos assim, a nossa configuração de uma window poderia ser semelhante a esta:
var win = new Ext.Window({
title:'Personnel'
,width:600
,height:400
,items:{xtype:'personnelgrid'}
});
win.show();
[Nota: A seguinte estrutura pode não funcionar em todas as situações, para excessões, por favor consulte este post (em inglês).]
Vamos fazer um exemplo para discutir:
Application.PersonnelGrid = Ext.extend(Ext.grid.GridPanel, {
border:false
,initComponent:function() {
Ext.apply(this, {
store:new Ext.data.Store({...})
,columns:[{...}, {...}]
,plugins:[...]
,viewConfig:{forceFit:true}
,tbar:[...]
,bbar:[...]
});
Application.PersonnelGrid.superclass.initComponent.apply(this, arguments);
} // eo function initComponent
,onRender:function() {
this.store.load();
Application.PersonnelGrid.superclass.onRender.apply(this, arguments);
} // eo function onRender
});
Ext.reg('personnelgrid', Application.PersonnelGrid);
O que nós fizemos aqui? Nóes extendemos Ext.grid.GridPanel criando uma nova classe (extension) Application.PersonnelGrid, e nós registramos ela com um novo xtype com o nome personnelgrid.
Nós estamos dando ao Grid todas as opções de configuração necessárias para se tornar o Grid Personal específico. Deste ponto em diante, temos um novo componente, um alicerce para o nosso aplicativo que podemos utilizar em qualquer lugar (window, panel, border, autônomo), onde a lista de pessoal é necessária. Nós podemos criá-lo, quer como:
var pg = new Application.PersonnelGrid();
ou utilizando este xtype (instalação preguiçosa):
var win = new Ext.Window({
items:{xtype:'personnelgrid'}
,....
});
O código acima não precisa e não deve funcionar dentro da função onReady(), porque ele não tem nada a ver com a estrutura DOM, que só cria um novo objeto JavaScript. Por isso, pode e, deve ser escrita em um arquivo separado (js/Application.PersonnelGrid.js), e ele pode e deve ser incluído na index.html como cabeçalho:
<script type="text/javascript" src="./js/Application.PersonnelGrid.js></script>
Até aí, tudo bem, temos quase tudo no lugar e (quase) tudo o que precisamos é fazer mais para continuar escrevendo a nossa pré-configurado classes, colocá-los no diretório ./js, e incluí-los na index.html e construir as isntâncias da nossa aplicação, como um quebra-cabeça que é montado a partir de peças.
Parece bom, assim?
Enfim, há um pouco mais para fazer.
Imagine que nós precisamos de um border layout com uma lista de links no west e um tab panel na região center. Clicando um link no west é criado uma nova tab no center. Agora, onde devemos colocar a lógica disto, event handler e a rotina de criação? No west ou no center?
Em nenhum deles. Por quê? Se temos uma classe pré-configurada que cria e exibe a lista de links west e pomos o exposto na mesma lógica, já não pode existir sem a região center. Nós apenas não pode usá-lo sem o centro, então não temos como criar tabs com o componente.
Se nós o colocamos no center, o resultado é o mesmo: não pode existir sem west.
O único componente que deve estar ciente da existência dos dois painéis (west e center) é o seu recipiente com o border layout, e este é o único lugar certo onde colocar componente que se inter-comunicam.
O que devemos fazer, então? O recipiente (border layout) deve monitorar eventos disparados pelo west e deverá criar guias no center como respostas a esses cliques. Um exemplo dos elementos que compõem a comunicação escrita desta maneira pode ser encontrado aqui: Saki's Ext Exemplos.
À medida que continuamos a escrever o nosso aplicativo, acontece de um grande número de arquivos JavaScript são incluídos (tenho cerca de 80 incluidos, em uma aplicação atualmente e esse número cresce a cada dia). Isso pode diminuir o desempenho de um sistema de aplicativos.
A melhor maneira de resolver isso é concatenar todos os arquivos JavaScript na ordem correta para criar um arquivo grande, e para apoucar-lo com algumas das minifying JavaScript ou ferramentas de compressão. Além disso, você não precisa da versão de depuração da biblioteca Ext para sistemas de aplicativos.
Em um sistema de aplicativos nós podemos incluir:
Para obter informações adicionais sobre minimização de fontes e criação de arquivos combinados, temos outro tutorial, que abrange este tema em profundidade.
É quase tudo o que há para se dizer sobre isso ... Existem técnicas específicas para determinadas classes Ext, há um monte de outros conhecimentos sobre server-side e client-side, mas o acima é o conceito global.
Happy coding!
Este tutorial é a tradução para o português do Brasil do tutorial Writing a Big Application in Ext