| Summary: Uma visão geral da biblioteca Ext e uma introdução sobre como usá-la para executar algumas tarefas comuns. Novos usuários devem começar por aqui. |
| Author: Fábio Vedovelli |
| Published: May 30, 2007 |
| Ext Version: 1.1 |
Languages: English Dutch Spanish Chinese Russian Portuguese French
|
Qualquer um que é novo na utilização da biblioteca Ext ou está tentando aprender um pouco mais está no lugar certo. Este tutorial caminhará pelos conceitos básicos e como sobre como conseguir colocar uma página dinâmica rodando rapidamente. Estou assumindo que você, leitor, tem alguma experiencia com Javascript e um entendimento básico de DOM (Document Object Model).
Contents |
Se ainda não baixou, você deve primeiro fazer o download da versão mais recente, que sempre pode ser encontrada em: http://extjs.com/download.
Há muitas opções diferentes para o que você poderá baixar, mas você provavelmente irá querer começar com a versão estável mais recente. Uma vez feito o download e o arquivo descompactado, um bom lugar para começar é explorando a pasta que contém os exemplos.
Vamos detalhar algumas das tarefas mais comuns que devem ser feitas em Javascript e como fazê-las utilizando a Ext. Se quiser experimentar enquanto estuda, você deve fazer o download do starter files IntroToExt.zip que usaremos para criar uma página com códigos Ext. Este arquivo zip contém 3 outros arquivos: ExtStart.html, ExtStart.js e ExtStart.css. Descompacte todos os 3 arquivos numa pasta dentro da pasta onde está a biblioteca Ext (por exemplo, se a Ext está em "C:\code\Ext\v1.0", crie a nova pasta dentro de "v1.0" chamada "tutorial"). Clique em ExtStart.html para abrir no seu browser e você verá uma mensagem informando que tudo está configurado corretamente. Se encontrar uma mensagem de erro de Javascript, siga as instruções da própria página para corrigir o erro.
Agora você está pronto para editar o arquivo ExtStart.js no seu editor preferido. Procure pelo seguinte código:
Ext.onReady(function() {
alert("Congratulations! You have Ext configured correctly!");
});
Ext.onReady é provavelmente o primeiro método que você usará em cada página. Este método é automaticamente chamado uma vez que o DOM está completamente carregado, garantindo que todos os elementos referenciados na sua aplicação estarão disponíveis quando o script rodar. você pode agora seguir em frente e deletar o alert() para adicionar alum código real que fará algo realmente útil!
Quase tudo que fizer em Javascript, em algum ponto envolverá referencia a um elemento específico em sua página, então você pode fazer coisas interessantes com ele. Usando Javascript tradicional, selecionar um node do DOM por ID é feito assim:
var myDiv = document.getElementById('myDiv');
Isso funciona perfeitamente, mas o objeto retornado (um node do DOM) não oferece muito no quesito poder ou conveniência. Para fazermos algo realmente útil com este node, você terá que escrever muito código. Também, será sua responsabilidade lidar com as diferenças de interpretação em cada um dos browser, o que poderá ser um saco.
Conhecendo o objeto Ext.Element.
A Element realmente é o coração da Ext porque a maioria do será feito envolverá o acesso aos elementos da página e a realização de determinadas ações com eles. A API dos elemtentos é fundamental para toda a biblioteca Ext e se você quiser dedicar seu tempo para aprender muito bem uma classe da Ext, Element deve ser sua escolha!
O código correspondente para pegar um elemento utilizando a Ext se parece com (a página ExtStart.htm contém um div com o id "myDiv", então vá em frente e adicione este código em ExtStart.js):
Ext.onReady(function() { var myDiv = Ext.get('myDiv'); });
Então pegamos o objeto. Mas o que há de tão interessante nisso?
Isso significa que você pode fazer todas as coisas úteis com pouquissimo código. Aqui estão alguns pequenos exemplos (veja a API da classe Element para a lista completa de tudo o que é possível fazer). Vá em frente e tente adicionar alguns destes códigos em ExtStart.js depois da linha onde você instanciou a captura do elemento 'MyDiv':
myDiv.highlight(); // O fundo do elemento será marcado com amarelo e desaparerá myDiv.addClass ('red'); // Adiona uma classe CSS (definido em ExtStart.css) myDiv.center(); // Centraliza elemento no viewport myDiv.setOpacity(.25); // Transforma um elemento em parcialmente transparente
De vez em quando é impraticável ou impossível selecionar os elementos por seu ID. Talvez o ID não foi informado ou você não sabe qual é ou há muitos elementos para que seja viável referenciar diretamente pelo ID. às vezes você pode querer selecionar os nodes baseado em alguma outra coisa que não o ID, como um atributo CSS ou ainda o nome de uma classe. Por isso, a Ext vem com uma poderosa biblioteca para trabalhar com DOM, chamada DomQuery.
A DomQuery pode ser utilizada sozinha, mas é mais comumente utilizada em conjunto com a Ext, que você usará dentro do contexto de selecionar elementos, assim você poderá interagir com eles utilizando o objeto Element. Por sorte, o objeto Element sozinho suporta a criação de uma fila de elementos, utilizando o método Element.select, que internamente utiliza a DomQuery para selecioná-los. Como um exemplo bem simples de como você poderá utilizar isso, o arquivo ExtStart.html contém alguns parágrafos (<p>), todos sem ID. Se você quiser facilmente selecionar cada um deles e fazer uma ação em todos de uma só vez, você deve fazer algo como:
// Resalta cada párrafo
Ext.select('p').highlight ();
Este exemplo demonstra um prático aspecto do Element.select - ele retorna um CompositeElement, que provê acesso a todos os elementos internos utilizando a interface Element. Isso te possibilita a facilmente agir em todas as intâncias do elemento retornado por Element.select sem a necessidade de um looping para mexer em cada um individualmente.
DomQuery suporta uma vasta gama de opções de seleção, incluindo a maioria dos seletores CSS3 do DOM, seguindo o padrão do W3C; XPATH básico, atributos do HTML e muito mais. Veja a API do DomQuery para um detalhamento completo dessa poderosa biblioteca.
Até agora, em nossos exemplos, todo o código que escrevemos foi diretamente dentro da função OnReady, o que significa que os códigos sempre foram executados imediatamente após o carregamento da página. Isso não nos dá muito controle: você provavelmente quererá que seu código seja executado respondendo a ações específicas ou eventos que você irá escolher para disparar estas ações, acessando funções que vinculará a esses eventos.
Vamos então começar um exemplo bem simples. Abra o ExtStart.js e edite para que seu código se pareça com:
Ext.onReady(function() {
Ext.get('myButton').on('click', function(){
alert("You clicked the button" );
});
});
O código será executado quando a página carregar, mas existe uma diferença importante. A função que contém o alert() está definida, mas não será executada imediatamente - ela está vinculada a um "handler" associado ao um clique em botão. Trocando em miúdos, este código quer dizer: "Faça a referência ao elemento com o id 'myButton' e associe a ele a função que será executada todas as vezes que alguém clicar neste elemento".
Da mesma forma, Element.select permite que você faça a mesma coisa, mas com um grupo inteiro de elementos de uma só vez. Por exemplo, para mostrar uma mensagem quando qualquer parágrafo na página de teste for clicado, podemos fazer assim:
Ext.onReady(function() {
Ext.select('p').on('click', function() {
alert("You clicked a paragraph") ;
});
});
Nestes dois exemplos, a função que será acessada quando o evento for disparado está escrita diretamente, sem a declaração explícita de uma função. O termo para este tipo de função é "função anônima" uma vez que ela existe sem ter um nome. você pode também associar um evento para ser manuseado por uma função explicitamente declarada, que é muito útil se você tenciona utilizá-la posteriormente e associá-la a multiplos eventos. Por exemplo, este código é funcionalmente equivalente ao do exemplo acima:
Ext.onReady(function() {
var paragraphClicked = function() {
alert("You clicked a paragraph");
}
Ext.select('p').on('click', paragraphClicked);
});
Até agora nós vimos como fazer uma ação genérica quando o nosso evento é acionado, mas como poderemos saber quando um elemento específico foi acionado para podermos fazer alguma ação nele? Isso é muito fácil - o método Element.on possui três parâmetros extremamente úteis para manusear funções (vamos apenas ver o primeiro aqui, mas você pode explorar a documentação da API para aprender mais sobre os detalhes do manuseamento de eventos). Nos exemplos anteriores nossa função de manuseamento ignorou estes parâmetros, mas com uma mudança simples, podemos prover um nível adicional de funcionalidade. O primeiro e mais importante parâmetro é o evento que ocorre. Ele é um objeto do evento, que é funcional entre todos os browsers e provê mais informação do que o evento padrão do browser. Por exemplo, o node do DOM que é o target pode ser recuperado com esta simples adição:
Ext.onReady(function() {
var paragraphClicked = function(e) {
Ext.get(e.target).highlight();
}
Ext.select('p').on('click', paragraphClicked);
});
Repare que o alvo (target) é um node do DOM, então nós primeiro recuperamos o elemento correspondente, então fazemos a ação que quisermos. Neste caso, nós destacamos o parágrafo.
Adicionalmente à biblioteca padrão que estivemos discutindo, EXT também inclui uma das mais ricas coleções de Widgets Javascript disponiveis atualmente. Há muito o que dizer e não há espaço em uma simples introdução como esta, mas podemos dar uma olhada em alguns dos widgets que as pessoas estão utilizando e veremos como é fácil trabalhar com eles.
Ao invés de um chato alerta "Hello World", vamos fazer algo um pouco melhor. Nos já temos um código escrito mais acima que destaca cada parágrafo quando clicado. Vamos modificar o código para também mostrar o texto do parágrafo que foi clicado num Message Box. Na função paragraphClicked, troque a linha:
Ext.get(e.target).highlight();
... por este código:
var paragraph = Ext.get(e.target);
paragraph.highlight( );
Ext.MessageBox.show({
title: 'Paragraph Clicked',
msg: paragraph.dom.innerHTML,
width:400,
buttons: Ext.MessageBox.OK,
animEl: paragraph
});
Há alguns novos conceitos sendo mostrados aqui que valem uma discussão. Na primeira linha estamos criando uma variável local chamada paragraph que conterá uma referencia ao elemento representado pelo node do DOM que foi clicado (neste caso nós sabemos que sempre será um parágrafo, uma vez que nosso evento click está associado à tag <p>). Por que estamos fazendo isso? Bem, olhando à frente, precisaremos referenciar a função para destacar o elemento e precisaremos também usar o mesmo elmento para pegar alguns parâmetros para o Message Box. Em geral, é uma má prática fazer multiplas chamadas à uma função para recuperar o mesmo valor ou referência ao objeto, então associando a uma variável local e reutilizando a variável, nós seremos bons desenvolvedores orientados a objetos!
Agora a chamada para o MessageBox demonstra o outro novo conceito para discutirmos. Numa primeira olhada, parece ser uma simples lista de parâmetros sendo passados para o método, mas se você olhar mais de perto, existe uma forma específica de fazer isso. O que está sendo passado para MessageBox.show() neste caso é somente um parâmetro: um objeto literal que contém uma gama de propriedades e valores. Em Javascript, um objeto literal é um objeto dinâmico e generico que é criado a qualquer tempo em que se use { e } englobando uma lista de propriedades nome/valor e o forma para estas propriedades é [nome da propriedade] : [valor da propriedade]. Você verá este padrão sendo usado extensivamente na Ext, então você deve aprender isso muito bem!
Por que usar um objeto literal? A principal razão é a flexibilidade. Novas propriedades podem ser adicionadas ou removidas do objeto literal a qualquer momento, ou definidas em qualquer ordem, enquanto a assinatura do método (a quantidade e o tipo de parâmetros esperados pelo método) nunca tem que mudar. Isso também é mais convenitente do lado da perspectiva dos desenvolvedores quando usando métodos com muitos parâmetros (como no caso do MessageBox.show). Por exemplo, vamos dizer que um método fictício foo.action tem quatro parâmetros opcionais, mas você só precisa passar um deles. Neste caso, seu código deverá ser: foo.action(null,null,null,'hello'). Contudo, se este método for escrito como um objeto literal, o código se parecerá com: foo.action({param4: 'hello'}). Muito mais fácil de utilizar e muito mais legível.
O grid é um dos mais populares widgets da Ext and comumente o primeiro que as pessoas querem utilizar, então vamos ver agora como é fácil de ter um grid básico funcionando. Remova todos os códigos escritos em ExtStart.js e coloque o seguinte código:
Ext.onReady(function() {
var myData = [
[' Apple',29.89,0.24,0.81,'9/1 12:00am'],
['Ext', 83.81,0.28,0.34,'9/12 12:00am'],
['Google',71.72,0. 02,0.03,'10/1 12:00am'],
['Microsoft',52.55,0.01,0. 02,'7/4 12:00am'],
['Yahoo!',29.01,0.42,1.47,'5 /22 12:00am']
];
var ds = new Ext.data.Store({
proxy: new Ext.data.MemoryProxy(myData),
reader: new Ext.data. ArrayReader({id: 0}, [
{name: 'company'},
{name: 'price', type: 'float'},
{name: ' change', type: 'float'},
{name: 'pctChange' , type: 'float'},
{name: 'lastChange', type: &# 39;date', dateFormat: 'n/j h:ia'}
])
});
ds.load();
var colModel = new Ext.grid.ColumnModel([
{header: "Company", width: 120, sortable: true, dataIndex: ' company'},
{header: "Price", width: 90, sortable: true, dataIndex: 'price'},
{header: "Change", width: 90, sortable: true, dataIndex: 'change'},
{header: & quot;% Change", width: 90, sortable: true, dataIndex: 'pctChange'},
{header: "Last Updated", width: 120, sortable: true,
renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
]);
var grid = new Ext. grid.Grid('grid-example', {ds: ds, cm: colModel});
grid.render( );
grid.getSelectionModel().selectFirstRow();
});
Apesar de parecer que tem coisa demais, tem apenas sete linhas de código no total! A primeira linha de código cria um array com dados a serem mostrados no grid. Num projeto real, você provavelmente irá querer carregar estes dados de alguma fonte dinâmica, como um banco de dados ou um web service. Em seguida, nós criamos e carregamos um data store, que informará à biblioteca como ler e formatar os dados. No próximo, definimos nosso modelo de coluna (column model) que lhe permite configurar opções para cada coluna do grid. Finalmente criamos o grid, passando para ele o data store e o column model, renderizando-o e selecionando a primeira linha. Como é fácil, não? Se tudo correu bem, você provavelmente verá algo como:
Claro que provavelmente deve ter alguns detalhes sobre este código que você não entendeu completamente neste ponto (como por exemplo o que vem a ser MemoryProxy?). O objetivo deste exemplo é mostrar como é simples de criar um extremamente rico e visualmente complexo componente de interface de usuário com pouquíssimas linhas de código. Aprender os detalhes será deixado como um execício para você. Há muitos recursos para ajudá-lo a aprender, incluindo os demos interativos e a documentação da API do grid.
Nós apenas visualizamos a ponta do iceberg aqui. Há dezenas de widgets para interface de usuário para você escolher dentro da Ext, incluindo layouts de páginas, tabs, menus, barras de ferramentas (toolbars), janelas (dialogs), árvores (tree view) e muito mais. Explore os exemplos da seção da documentação da API para uma visualização de tudo o que está disponível.
Uma vez que sua página foi criada e você sabe como interagir com ela usando Javascript, você provavelmente sabe como pegar dados de um servidor remoto, provavelmente para acessar e gravar dados num banco de dados. Fazer isso assincronamente via Javascript sem atualizar a página é conhecido como AJAX e a Ext tem um excelente suporte nativo a isso. Por exemplo, uma tarefa comum é gerenciar uma interação do usuário, postando alguma coisa assincronamente no servidor e depois atualizando um elemento da interface utilizando a resposta dada pelo servidor remoto. Temos aqui um exemplo simples de um formulário contendo um campo de texto, um botão e um div usado para mostrar a mensagem (Nota: você pode adicionar este código a ExtStart.html se quiser, mas você terá que ter acesso a um servidor web para poder rodar o código abaixo):
<div id="msg" style="visibility: hidden"></div> Name: <input type="text" id="name" /> <br /> <input type="button" id="oKButton" value="OK" />
Em seguida, vamos adicionar o Javascript necessário para pegar nossos dados e postar em um processo server-based (troque todos os códigos existentes em ExtStart.js por este):
Ext.onReady(function(){
Ext.get('oKButton').on('click', function(){
var msg = Ext.get("msg");
msg.load({
url: [server url], // <-- replace with your url
params: "name=" + Ext.get('name').dom. value,
text: "Updating..."
});
msg.show();
});
});
Espero que o padrão geral tenha começado a parecer familiar! O código é associado ao botão okButton com um objeto de elemento e a ele é associada uma função anônima que fará toda a ação quando alguém clicar no botão. Dentro do gerenciador do clique, nós usamos uma classe especial da Ext chamada UpdateManager - esta classe envia a chamada AJAX, recebe a resposta e atualiza outro elemento. O UpdateManager pode ser usado diretamente, como estamos fazendo aqui ou podemos acessá-lo através do elemento que queremos atualizar (neste caso o div 'msg') usando o método Element.load. Quando o Element.load é utilizado, a resposta do servidor é automaticamente inserida no elemento utilizando innerHTML. Simplesmente passe a URL que processará a requisição, os parâmetros na forma de QueryString (neste caso passando o valor do campo 'name') e o texto para ser mostrado no div 'msg' enquanto a requisição é processada. Mostre o elemento div (ele é escondido por padrão) e é só isso! Claro, como muitas coisas na Ext, há muito mais coisas no UpdateManager, bem como diferentes maneiras de processar requisições AJAX, em diferentes situações, mas isso mostra o quão fácil é ter um bom exemplo pronto para uso.
O último pedaço do quebra-cabeças AJAX é o processamento do lado do servidor web, que recebe a requisição e devolve a resposta para a página. Este processo pode ser uma página, um servelet, um HTTP handler, um web service, até mesmo um script Perl ou CGI - qualquer coisa que estiver no servidor e que processe uma chada HTTP. Infelizmente, devido a esta vasta gama, não há como mostrar um exemplo padrão que mostrará todas as possibilidades. Aqui estão alguns exemplos em algumas linguagens populares para que você possa começar (este código simplesmente mostra o que foi passado no campo 'name' de volta para o browser com 'From server: ' adicionado e é inserido no div 'msg'):
<?php if(isset($_POST['name'])) {
echo 'From Server: '.$_POST['name'];
}
?>
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Form["name"] != null)
{
Response.Write("From Server: " + Request.Form["name"]);
Response.End();
}
}
<cfif StructKeyExists(form, "name")> <cfoutput>From Server: #form.name#</cfoutput> </cfif>
O verdadeiro desafio quando trabalhando com o processamento via AJAX envolve toda a codificação requerida para processar apropriadamente e formatar dados reais estruturados no servidor. Há muitos formatos a escolher que as pessoas comumente usam (tanto XML como JSON). Há muitas blbliotecas específicas em cada lingugem para lidar com processamento AJAX que trabalham bem com EXT, uma vez que a Ext é uma liguagem neutra no que diz respeito ao servidor. Uma vez que o resultado é enviado para a página num formato adequado, Ext não se importa o que acontece no servidor.
Agora que você tem uma primeira impressão do que é a Ext e o que ela oferece, existem muitos recursos disponíveis para ajudar a chegar ao próximo nível: