Ext JS - Learning Center

Tutorial:Introduction to Ext 2.0 (Brazilian Portuguese)

From Learn About the Ext JavaScript Library

Revision as of 17:19, 18 March 2009 by Minholi (Talk | contribs)
(diff) ← Older revision | Current revision (diff) | Newer revision → (diff)
Jump to: navigation, search
Summary: Uma visão geral da biblioteca Ext e uma introdução ao uso da Ext para completar algumas tarefas comuns de aplicação. Novos usuários devem começar aqui.
Author: Brian Moeskau (Translator: Marcelo Minholi)
Published: November 1, 2007
Ext Version: 2.0
Languages: en.png English cn.png Chinese jp.png Japanese

kr.png Korean it.png Italian id.png Bahasa Indonesia pt_BR.png Brazilian Portuguese

Este tutorial é da versão 2.0 da Ext. A versão 1.x deste tutorial continua disponível.

Qualquer novato na utilização da biblioteca Ext ou que esteja tentando aprender mais sobre ela veio ao lugar certo. Este tutorial irá discorrer sobre os conceitos básicos da Ext e como obter uma página dinâmica pronta e rodando rapidamente. Ele assume que o leitor tem alguma experiência com Javascript e um entendimento básico do modelo de objetos de documento (DOM) do HTML.

Configurar a Ext

Se você não fez isso ainda, primeiro você irá querer ter a Ext configurada. Veja este Guia Inicial para mais detalhes.

Vamos Começar

Descarregar Arquivo de Exemplo

Nós estamos prestes a discorrer sobre algumas das tarefas mais comuns que as pessoas tem que cumprir em Javascript e como perfazê-las usando a Ext. Se você gostaria de testar a medida que for avançando, você deve fazer o download dos arquivos iniciais em IntroToExt2.zip que nós iremos usar para construir uma página com código Ext funcional.

Este zip contém quatro arquivos: ExtStart.html, ExtStart.js, ExtStart.css e ajax-example.php.

  • Descompacte todos os 4 arquivos em uma pasta diretamente acima da pasta onde a Ext está instalada (por exemplo, se a Ext estiver em "C:\code\ext-2.0\," crie uma nova pasta dentro de "ext-2.0\" chamada "tutorial" ex.: "C:\code\ext-2.0\tutorial\").
  • Dé um clique duplo no ExtStart.html que isso irá carregar o seu navegador padrão, e você deverá receber uma mensagem dizendo a você que tudo está configurado corretamente. Se você receber um erro de JavaScript, por favor siga as instruções da página para tê-la funcionando.

Agora você está pronto para abrir o ExtStart.js na sua IDE favorita ou editor de texto e dar uma olhada nele:

Ext.onReady(function() {
	alert("Congratulations!  You have Ext configured correctly!");
});

Ext.onReady é provavelmente o primeiro método que você irá usar em todas as páginas. Esse método é automaticamente chamado assim que o DOM esteja totalmente carregado, garantindo que quaisuer elementos da página que você queira referenciar estejam disponíveis quando o script rodar. Você pode prosseguir e deletar a linha do alert() e agora poderemos começar a adicionar algum código real que realmente fará algo útil!

Element: O Coração da Ext

Praticamente tudo que você faz em Javascript irá em algum momento envolver a referência a elementos específicos da sua página para que você possa fazer coisas interessantes com eles. Usando o Javascript tradicional, selecionar um nodo DOM é feito de maneira parecida com isso:

var myDiv = document.getElementById('myDiv');

Isso irá funcionar bem, mas o objeto que é retornado (um nodo DOM) não oferece muito em termos de poder ou conveniência. De forma a fazer algo útil com aquele nodo, você continuará tendo que escrever um monte de código de base por conta própria. Também será sua responsabilidade lidar com as diferenças sobre como o nodo pode ser usado de navegador para navegador, o que pode ser desencorajador.

Entre no objeto Ext.Element. A Element realmente é o coração da Ext já que a maioria do que você irá fazer envolverá obter acesso a Elementos e realizar ações neles. A API da Element é fundamental para toda a biblioteca Ext, e se você gastar algum tempo para realmente aprender apenas uma classe da Ext bem, a Element deve ser ela!

O código correspondente para pegar um Element pelo ID se parece com isso (a página inicial ExtStart.html contém um div com o id "myDiv," então vamos em frente e adicionar este código ao ExtStart.js):

Ext.onReady(function() {
	var myDiv = Ext.get('myDiv');
});

Então nós estamos retornando um objeto Element, agora o que há de interessante nisto?

  • A Element contém a maioria dos métodos e propriedades DOM que você irá precisar, fornecendo uma conveniente, unificada e intreface DOM cross-browser (e você continuará podendo acessar diretamente o nodo DOM quando você precisar via Element.dom)
  • O método Element.get() fornece caching interno, então multiplas chamadas para obter o mesmo objeto são incrivelmente rápidas
  • As ações mais comuns relizadas em nodos DOM são construídas dentro de métodos diretos, cross-browser da Element. (adicionar/remover classes CSS, adicionar/remover manipuladores de eventos, posicionamento, dimensionamento, animação, arrastar/soltar, etc.)

Isso significa que você pode fazer todos os tipos de coisas úteis com código realmente mínimo. Aqui estão apenas alguns exemplos simples (veja a documentação da API da Element para a lista completa de tudo que você pode fazer). Siga em frente e tente adicionar alguns desses ao ExtStart.js depois da linha anterior onde nós pegamos o Elemento 'myDiv':

myDiv.highlight();      // O plano de fundo do elemento será marcado em amarelo e então esmaecer de volta
myDiv.addClass('red');  // Adicione uma classe CSS personalizada (definida no ExtStart.css)
myDiv.center();         // Centralize o elemento na área visível
myDiv.setOpacity(.25);  // Faça o elemento ficar parcialmente transparente

Selecionando Nodos DOM

Muitas vezes não é prático ou mesmo impossível selecionar nodos DOM pelo ID. Talvez o ID não tenha sido definido, ou você não o conhece, ou há muitos elementos para referenciá-los de forma prática pelo ID. Algumas vezes você pode querer selecionar nodos baseando-se em alguma outra coisa que não o ID, como um atributo ou um nome de classe CSS. Por essas razões, a Ext vem com uma biblioteca extremamente poderosa de seleção DOM chamada DomQuery.

A DomQuery pode ser usada como uma biblioteca isolada, mas mais comumente quando usando a Ext, você irá usá-la no contexto da seleção de Elementos para que assim você possa agir neles via interface da Element. Felizmente, o objeto Element por si só suporta consultas através do método Element.select, que internamente usa DomQuery para selecionar elementos. Como um exemplo simples de como você pode usar isso, o arquivo ExtStart.html contém várias tags de parágrafo (<p>), nenhuma das quais possuem ids. Se você quiser selecionar facilmente todos os parágrafos e realizar uma ação em todos eles de uma vez, você pode fazer algo como isto:

// Marca todos os parágrafos
Ext.select('p').highlight();

Esse exemplo demonstra um aspecto muito útil do Element.select—ele retorna um CompositeElement, que provê acesso a cada Elemento nele contido via interface da Element. Isso permite que você aja facilmente em todas as instâncias retornadas pelo Element.select sem estruturas de repetição ou tocar cada uma individualmente.

A DomQuery suporta uma extensa variedade de opções de seleção, incluindo a maioria dos seletores DOM do CSS3 da W3C, XPath básico, atributos HTML e muito mais. Por favor veja a documentação da API da DomQuery para detalhes completos dessa poderosa biblioteca.

Respondendo a Eventos

Até então em nossos exemplos, todo o código que nós escrevemos foi posicionado diretamente dentro da função onReady, o que significa que ele sempre será executado imediatamente após o carregamento da página. Isso não nos dá muito controle—você normalmente irá querer que seu código execute em resposta a ações específicas ou eventos que você escolheu para manipular. Para fazer isso, você define manipuladores de eventos que poderão responder aos eventos usando funções que você irá atribuir.

Vamos começar com um exemplo simples. Abra o ExtStart.js e edite ele para que seu código se pareça com esse:

Ext.onReady(function() {
    Ext.get('myButton').on('click', function(){
        alert("Você clicou o botão");
    });
});

O código continuará sendo executado quando a página carregar, mas há uma diferença importante. A função contendo o alert() está definida, mas não é atualmente executada de imediato—ela é atribuída ao "handler" do evento click do botão. Descrito em Português simples, o código pode ser lido: "Pegue uma referência ao Elemento com o id 'myButton' e atribua uma função para ser chamada toda vez que alguém clicar no Elemento."

Não por acaso, o Element.select permite a você fazer a mesma coisa, mas com um grupo inteiro de elementos de uma vez. Por exemplo, para exibir sua mensagem quando qualquer parágrafo na nossa página de testes for clicado, nós poderiamos fazer isso:

Ext.onReady(function() {
	Ext.select('p').on('click', function() {
		alert("Você clicou um parágrafo");
	});
});

Nesses dois exemplos, a função de manipulação do evento é simplesmente declarada em linha, sem dar a ela um nome de função. O termo para esse tipo de função é "função anônima" já que ela é declarada sem nunca ter sido declarada. Você também pode atribuir um evento para ser manipulado por uma função declarada, o que é especialmente útil se você quiser reutilizar a função e tiver que manipular múltiplos eventos. Por exemplo, esse código é equivalente funcionalmente ao exemplo anterior:

Ext.onReady(function() {
    var paragraphClicked = function() {
      alert("Você clicou um parágrafo");
    }
    Ext.select('p').on('click', paragraphClicked);
});

Até então nós temos olhado para a realização de uma ação genérica quando nosso é evento é disparado, mas como nós poderíamos saber qual Elemento especificamente disparou o evento para que nós possamos realizar alguma ação sobre ele? Isso torna-se muito fácil—o método Element.on passa três parâmetros extremamente úteis para a função de manipulação do evento (nós só estamos olhando para o primeiro aqui, mas você poderia explorar a documentação da API para aprender mais detalhes sobre manipulação de eventos). Nós nossos exemplos anteriores a nossa função de manipulação estava ignorando esses parâmetros, mas com uma simples mundança, nós podemos fornecer um nível adicional de funcionalidade. O primeiro, e mais importante, parâmetro é o evento que ocorreu. Esse é atualmente um Ext.EventObject, que é normalizado entre navegadores e fornece mais informações que o evento padrão do navegador. Por exemplo, o nodo DOM alvo do evento pode ser recuperado com essa simples adição:

Ext.onReady(function() {
	var paragraphClicked = function(e) {
		Ext.get(e.target).highlight();
	}
	Ext.select('p').on('click', paragraphClicked);
});

Note que o alvo é um nodo DOM, então nós primeiros recuperamos o Elemento correspondente, então realizamos qualquer ação que queiramos com ele. Neste caso, nós marcamos visualmente o parágrafo.

Usando Widgets

Em complemento à biblioteca javascript principal que nós já viemos discutindo, a Ext também inclui um dos conjuntos de widges UI Javascript mais úteis disponíveis atualmente. Há muito o que cobrir nesta introdução, mas iremos dar uma olhada em alguns dos widgets que as pessoas normalmente mais usam e como eles são fáceis de se trabalhar.

MessageBox

Ao invés de uma massante caixa de mensagem "Hello World", vamos adicionar um pouco de tempero. Nós já temos código que escrevemos na seção anterior que marca cada parágrafo quando você clica nele. Vamos modificar aquele código e mostrar o texto do parágrafo que foi clicado em uma caixa de mensagem. Na função paragraphClicked acima, substitua a linha:

Ext.get(e.target).highlight();

...por esse 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 exibidos aqui que vale a pena discutir. Na primeira linha, nós agora estamos criando uma variável local chamada paragraph que irá conter uma referência ao Elemento representando o nodo DOM que foi clicado (nesse caso nós sabemos que ele será sempre um parágrafo já que o nosso evento click está associado apenas com tags <p>). Por que estamos fazendo isso? Bom, olhando adiante por um momento, nós iremos precisar de uma referência ao Elemento para marcá-lo, e iremos também usar o mesmo Elemento para alguns dos parâmetros da MessageBox. Em geral, é uma má prática fazer a mesma função ser chamada múltiplas vezes para recuperar o mesmo valor ou referência a um objeto, então ao atribuir a ela uma variável local e reutilizar a variável, nós estaremos sendo bons desenvolvedores orientados a objetos!

Agora, é a chamada da MessageBox, que demonstra os outros novos conceitos para que discutamos. Numa primeira olhada, isso pode parecer apenas com uma linha de parâmetros sendo passados para um método, mas se você olhar mais atentamente, há uma sintaxe muito específica. Que está atualmente sendo passada para o MessageBox.show() neste caso sendo apenas um parâmetro: uma literal de objetos que contém um conjunto de propriedades e valores. Em JavaScript, uma literal de objetos é um objeto genérico dinâmico que é criado toda vez que você usar os caracteres { e } delimitando uma lista de propriedades nome/valor, e o formato dessas propriedades é [nome da propriedade] : [valor da propriedade]. Você irá ver esse padrão ser usado extensivamente pela Ext, então você deve aprendê-lo bem!

Por que usar uma literal de objetos? A principal razão é a flexibilidade. Novas propriedades podem ser adicionadas ou removidas da literal de objetos em qualquer momento, ou definidas em qualquer ordem, enquanto a assinatura do método (o número e os tipos de parâmetros esperados por um método) nunca precisa mudar. Isso também é muito mais conveniente da perspectiva do desenvolvedor final quando usando métodos com muitos parâmetros adicinais (como no caso do MessageBox.show). Por exemplo, vamos dizer que um método fictício foo.action tem quatro parâmetros adicionais, mas você precisa apenas passar um para ele. Neste caso, seu código se parecerá com isso: foo.action(null, null, null, 'hello'). Entretanto, se aquele método estivesse pegando uma literal de objetos, o código se pareceria com este: foo.action({ param4: 'hello' }). Muito mais fácil de usar, muito mais legível.

Grid

O grid é um dos widgets mais populares na Ext, e usualmente é o primeiro que as pessoas querem ver, então vamos dar uma olhada no quão fácil é ter um grid básico pronto e rodando. Substitua qualquer código existente que você tiver no ExtStart.js e então ele se parecerá com este:

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 myReader = new Ext.data.ArrayReader({}, [
		{name: 'company'},
		{name: 'price', type: 'float'},
		{name: 'change', type: 'float'},
		{name: 'pctChange', type: 'float'},
		{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
	]);
 
	var grid = new Ext.grid.GridPanel({
		store: new Ext.data.Store({
			data: myData,
			reader: myReader
		}),
		columns: [
			{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: '% Change', width: 90, sortable: true, dataIndex: 'pctChange'},
			{header: 'Last Updated', width: 120, sortable: true, 
				renderer: Ext.util.Format.dateRenderer('m/d/Y'), 
	                        dataIndex: 'lastChange'}
		],
		viewConfig: {
			forceFit: true
		},
		renderTo: 'content',
		title: 'My First Grid',
		width: 500,
		autoHeight: true,
		frame: true
	});
 
	grid.getSelectionModel().selectFirstRow();
});

Enquanto isto pode parecer muito, na verdade são apenas 4 linhas de código no total (3 se você não contar os dados de teste)!

  • A primeira linha de código cria um conjunto de dados de teste para serem mostrados no grid. Em projetos reais, você provavelmente irá carregar esses dados de fontes dinâmicas como um banco de dados ou um web service.
  • Em seguida, nós criamos um leitor de dados que sabe como interpretar os dados e convertê-los em registros úteis para a armazenagem de dados do grid. Há vários tipos diferentes de classes Leitoras para diferentes tipos de dados.
  • Em seguida, nós criamos o widget grid, passamos todos os tipos de valores de configuração, incluindo:
    • Uma nova armazenagem de dados, configurada em tempo de execução com nossos dados de teste e leitor
    • A definição do modelo de colunas usando a configuração columns
    • Opções adicionais para configurar características específicas do grid
  • Finalmente, nós dizemos ao grid para marcar sua primeira linha via SelectionModel.

Quão fácil isto é? Se tudo correr bem, você deverá terminar com algo próximo da aparência disso:

Image:IntroToExt2_grid.gif

Claro que, haverão detalhes específicos sobre esse código que você não entenderá completamente neste ponto. A intenção desse exemplo é mostrar como é possível criar um componente de interface de usuário extremamente rico e complexo visualmente com pouquíssimas linhas de código—aprender os detalhes será deixado como um exercício para o leitor. Há muitos recursos para ajudá-lo com o aprendizado do grid, incluindo os demos interativos de grid e a documentação da API da GridPanel.

E Muito Mais...

Nós estamos olhando apenas para o topo do iceberg aqui. Há literalmente dúzias de widgets de UI para escolher na Ext, incluindo layouts automáticos de página, abas, menus, barras de ferramentas, diálogos, visão em árvore e muito mais. Por favor explore os exemplos interativos para uma visão geral de tudo que está disponível.

Usando Ajax

Uma vez que você tenha sua página criada e saiba como interagir com ela através do Javascript, você irá provavelmente querer saber como receber e enviar dados a partir de um servidor remoto, mais comumente para carregar e salvar dados de um banco de dados no servidor. Fazer isso assincronamente via Javascript sem recarregamento da página é comumente conhecido como Ajax, e a Ext tem suporte excelente a Ajax implementado internamente. Por exemplo, um objetivo comum é manipular uma interação do usuário, enviar alguma coisa para o servidor assincronamente, e então atualizar um elemento da UI em resposta à ação. Aqui está um exemplo de um formulário HTML muito simples contendo um campo de entrada de texto, um botão, e um div usado para mostrar a mensagem (Nota: você pode adicionar esse código ao ExtStart.html se você quiser continuar acompanhando, mas você terá que ter acesso a um servidor web para rodar o código de servidor abaixo):

<div>
    Name: <input type="text" id="name" />
    <input type="button" id="okButton" value="OK" />
</div>
<div id="msg"></div>

Em seguida, nós iremos adicionar o Javascript necessário para pegar nossos dados e postá-los em um processo baseado no servidor (substitua qualquer código existente no ExtStart.js por este):

Ext.onReady(function(){
	Ext.get('okButton').on('click', function(){
		var msg = Ext.get('msg');
		msg.load({
			url: 'ajax-example.php', // <-- mude se necessário
			params: 'name=' + Ext.get('name').dom.value,
			text: 'Atualizando...'
		});
		msg.show();
	});
});

Nota: Esse exemplo só irá rodar em um servidor web. A URL no seu navegador deverá começar com http:// e não file:// ou a transação Ajax não irá funcionar! O Localhost irá funcionar bem, mas precisa ser via http.

Felizmente o padrão geral está começando a parecer familiar agora! O código está tratando a entrada do okButton com um objeto Element e atrelando uma função anônima que irá manipular o evento se alguém clicar no botão. Dentro do manipulador do click, nós estamos usando uma classe especial presente na Ext chamada de Updater—essa classe torna o envio de uma requisição Ajax, recebimento de uma resposta e atualização de outro Elemento algo extremamente trivial. A Updater pode ser usada diretamente, ou como estamos fazendo aqui, ela pode ser acessada através do Elemento que queremos atualizar (neste caso o div 'msg') usando o método Element.load. Quando o Element.load é usado, a resposta do servidor automaticamente substitui o innerHTML do Elemento. Apenas passe a ele a URL do processo baseado no servidor que irá manipular a requisição, os parâmetros querystring a serem processados (neste caso passando o valor do campo 'name') e o texto a ser mostrado no innerHTML do Elemento enquanto a requisição estiver sendo processada. Mostre o div msg (já que ele começa oculto por padrão) e é isso! Claro, como a maioria das coisas na Ext, há muitas outras opções suportadas pela Updater, assim como diferentes maneiras de processar requisições Ajax em diferentes situações (veja a classe Ext.Ajax para mais acesso direto à funcionalidades Ajax), mas isso mostra quão fácil é ter um exemplo básico pronto e rodando.

A última peça do quebra-cabeças do Ajax é o processo no servidor web que manipula a requisição e retorna a resposta para a página. Esse processo pode ser uma página no servidor, um servlet, um manipulador HTTP, um web service, até um script Perl ou CGI—ou seja, qualquer coisa que possa residir em um servidor web e processar requisições HTTP. Infelizmente, devido a essa variedade não há como dar um exemplo padrão que possa cobrir todas as possibilidades. Aqui estão alguns exemplos em algumas linguagens comuns que esperamos possam ajudá-lo a começar (esse código simplesmente retorna qualquer coisa que for passada pelo campo nome de volta para o cliente com 'Do Servidor: ' adicionado no começo, e isso acaba escrito no div 'msg'). O exemplo PHP foi incluído para download como 'ajax-example.php' mas fique a vontade para substituí-lo pelo código de servidor da sua preferência:

Plain PHP

<?php if(isset($_POST['name'])) {
		echo 'Do Servidor: '.$_POST['name'];
	}
?>

CakePHP

<?php if(isset($this->data['name'])) {
		$this->flash('Do Servidor: '.$this->data['name']);
	}
?>

Django

from django.http import HttpResponse
 
def ajax_request(request):
    return HttpResponse('Do Servidor: %s' % request.POST.get('name', 'nada'))

Perl

#!/usr/bin/perl
use strict;
use warnings;
use CGI;
 
my $Query = new CGI;
 
print $Query->header();
print "Do Servidor: ".$Query->param('name');
 
exit;

ASP.Net

protected void Page_Load(object sender, EventArgs e)
{
	if (Request["name"] != null)
	{
		Response.Write("Do Servidor: " + Request["name"]);
		Response.End();
                //Note: the call to Response.End() will throw an 
                //exception (that's what it's designed to do). It's
                //OK to simply catch it and ignore it; depending on
                //your use case, you may find that necessary. 
	}
}

ColdFusion

<cfif StructKeyExists(form, "name")>
    <cfoutput>From Server: #form.name#</cfoutput>
</cfif>

    or using ColdFusion Scripting (cfscript)

if (StructKeyExists(form, "name")) {
        writeoutput("Do Servidor: " & form.name);
        }

JSTL (JSP)

From Server: ${param.name}

Ruby on Rails

render :text => "Do Servidor: #{params[name]}"


Os reais desafios ao lidar com processamento Ajax envolvem todo o código de baixo nível requerido para processar e formatar apropriadamente dados estruturados reais no servidor. Há vários formatos para escolher dentre os que as pessoas normalmente usam (a maioria entre JSON ou XML). Também há muitas bibliotecas específicas de linguagem disponíveis para lidar com processamento Ajax que podem funcionar bem com a Ext, já que a Ext é neutra quanto a linguagem inerente ao servidor. Tão logo o resultado seja enviado para a página na formatação de dados apropriada, a Ext não liga para o que acontece no servidor! Por favor veja nossa lista de recursos específicos por plataforma para informações adicionais sobre frameworks e ferramentas para o lado do servidor.

E Agora?

Agora que você teve uma pequena amostra do que é a Ext e o que ela tem para oferecer, há muitos recursos disponíveis para ajudá-lo a realmente mergulhar no próximo nível: