Criando uma Aplicação CRUD com ExtJS 4 MVC: Parte 2

11 Sep 2012
10 mins read

Parte 2 da série de posts explicando passo a passo como criar uma aplicação simples com ExtJS 4 usando o MVC.

Este tutorial está dividido em 5 partes - hoje vamos ver a segunda parte:

  1. Preparando o Ambiente e montando o Projeto (Parte 1)
  2. Criando o Model e Store (Parte 2)
  3. Criando a View - Grid (Parte 3)
  4. Criando a View - Formulário (Parte 4)
  5. Criando o Controller (Parte 5)

A segunda parte inclui:

  1. Criando o Model - Contato
  2. Criando a Store - Contatos
  3. Criando o Código PHP - CRUD

1 - Criando o Model - Contato

Como vamos trabalhar com uma coleção de dados que serão carregados do banco de dados, precisamos de um Model para representá-los. Nesse caso, o nosso Model terá os mesmos campos da tabela Contatos. Para isso, vamos criar um arquivo chamado Contato.js dentro da pasta app/model:

[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]
Ext.define('ExtMVC.model.Contato', {
extend: 'Ext.data.Model',
fields: ['id', 'name', 'phone', 'email']
});
[/code]

A linha 1 chama a atenção pelo nome da classe: ExtMVC.model.Contato

A convenção do nome da classe (Contato) é sempre o nome da entidade que estamos representando no singular!

2 - Criando a Store – Contatos

Agora precisamos criar a Store que quando carregada terá uma coleção de ExtMVC.model.Contato na memória. Para isso, vamos criar um arquivo chamado Contatos.js dentro da pasta app/store:

[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]
Ext.define('ExtMVC.store.Contatos', {
extend: 'Ext.data.Store',
model: 'ExtMVC.model.Contato',
autoLoad: true,
pageSize: 35,
autoLoad: {start: 0, limit: 35},

proxy: {
type: 'ajax',
api: {
create: 'php/criaContato.php',
read: 'php/listaContatos.php',
update: 'php/atualizaContato.php',
destroy: 'php/deletaContato.php',
},
reader: {
type: 'json',
root: 'contatos',
successProperty: 'success'
},
writer: {
type: 'json',
writeAllFields: true,
encode: true,
root: 'contatos'
}
}
});
[/code]

Vamos então à explicação de algumas linhas de código:

Na linha 1 temos a declaração do nome da classe: ExtMVC.store.Contato

A convenção do nome da classe da Store é o nome da entidade que estamos representando no plural – Contatos – pois estamos representando uma coleção de Contatos!

Na linha 3 temos a declaração do Model que estamos representando. Temos que colocar o nome completo da classe (ExtMVC.store.Contato).

Na linha 4 temos a declaração do autoLoad. Isso significa que não precisamos pedir para a Store buscar os dados no servidor manualmente. No momento que a Store for instanciada, ela automaticamente irá carregar os dados para nós.

Na linha 5 temos a declaração do pageSize. Essa configuração é a quantidade de registros que queremos que apareçam no grid. Como vamos usar uma barra de paginação, essa é a quantidade de registros que vamos carregar por vez da base de dados. Isso é útil, por exemplo, se tivermos 1 milhão de registros no banco de dados, não queremos mostrar tudo de uma só vez pois é muita informação. E com a barra de paginação, mostramos um pouco de cada vez e o usuário pode navegar pela informação.

Na linha 6 temos a declaração do autoLoad novamente, mas dessa vez dizendo que queremos que o primeiro registro seja o de número 0 (zero) e vamos trazer o limite de 35 do banco de dados. Depois no PHP vamos ver como tratar esses dados.

A partir da linha 8 temos a declaração do Proxy, a classe responsável por dizer COMO vamos nos comunicar com o servidor. Nesse caso:

Na linha 9, dizemos que vamos nos comunicar com o servidor através de requisições Ajax.

Nas linhas 10 a 15 declaramos as urls que serão chamadas para realizar as operações de CRUD (create, read, update, destroy).

Nas linhas 16 a 20 dizemos como e qual o formato da informação que deve vir do servidor. Na linha 17 dizemos que vamos ler um JSON; na linha 18 dizemos que a coleção/array de contatos devem vir dentro de uma propriedade chamada “contatos”; e na linha 19 dizemos que a propriedade que vai dizer se deu tudo certo no servidor ou não se chama “success”.

O JSON abaixo é um exemplo de dado que será lido do servidor:

[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]
{
"success":true,
"total":"2",
"contatos":[
{
"id":"1","email":"contact0@blog.com.br","name":"Contact0","phone":"(000) 000-0000"
},{
"id":"2","email":"contact1@blog.com.br","name":"Contact1","phone":"(000) 000-0000"
}
]
}
[/code]

E nas linhas 21 a 26 dizemos como e qual é formato da informação que será enviada ao servidor. Na linha 22 dizemos que iremos enviar um JSON; na linha 23 dizemos que mesmo que apenas 1 campo do Model seja atualizado, sempre iremos enviar todos os campos; na linha 24 dizemos que queremos que os dados sejam encodados com Ext.encode() e finalmente, na linha 25 dizemos que todos os dados serão enviados ao servidor dentro de uma configuração “contatos”.

Pronto! O mais legal do ExtJS é que sempre que fizermos um update, delete ou create em um modelo da Store, a própria Store vai fazer tudo para a gente, não vamos precisar nos preocupar em chamar o servidor manualmente!

3 - Criando o Código PHP – CRUD

Bem, já vou deixando uma OBS bem grande aqui para deixar claro que NÂO programo em PHP; a minha praia é Java! rs – Se coloco Java, muita gente iria ter dificuldades, mas como PHP é a língua que mais pessoas irão entender e é a mais simples para criar esse código, vou usar PHP. O objetivo aqui é apenas mostrar a lógica usada no servidor e não boas práticas de PHP, ok?

3.1 – Conectando ao banco de dados

O objetivo do código abaixo é apenas fazer conexão com o bando de dados – arquivo conectar.php que está dentro do diretório php:

[code lang="php" firstline="1" toolbar="true" collapse="false" wraplines="false"]
<?php

//nome do servidor (127.0.0.1)
$servidor = "127.0.0.1";

//usuário do banco de dados
$user = "root";

//senha do banco de dados
$senha = "root";

//nome da base de dados
$db = "blog";

//executa a conexão com o banco, caso contrário mostra o erro ocorrido
$conexao = mysql_connect($servidor,$user,$senha) or die (mysql_error());

//seleciona a base de dados daquela conexão, caso contrário mostra o erro ocorrido
$banco = mysql_select_db($db, $conexao) or die(mysql_error());

?>
[/code]

3.2 – Buscando todos os Contatos

O objetivo do código abaixo é pegar os parâmetros enviados pelo ExtJS, realizar a busca no banco de dados por todos os contatos dentro do limite estabelecido pela paginação e formatar no formato JSON que declaramos dentro do Proxy da Store – arquivo listaContatos.php que está dentro do diretório php:

[code lang="php" firstline="1" toolbar="true" collapse="false" wraplines="false"]
<?php
//chama o arquivo de conexão com o bd
include("conectar.php");

$start = $_REQUEST['start'];
$limit = $_REQUEST['limit'];

$queryString = "SELECT * FROM contact LIMIT $start, $limit";

//consulta sql
$query = mysql_query($queryString) or die(mysql_error());

//faz um looping e cria um array com os campos da consulta
$contatos = array();
while($contato = mysql_fetch_assoc($query)) {
$contatos[] = $contato;
}

//consulta total de linhas na tabela
$queryTotal = mysql_query('SELECT count(*) as num FROM contact') or die(mysql_error());
$row = mysql_fetch_assoc($queryTotal);
$total = $row['num'];

//encoda para formato JSON
echo json_encode(array(
"success" => mysql_errno() == 0,
"total" => $total,
"contatos" => $contatos
));
?>
[/code]

Na linha 5 pegamos o parâmetro start do request que foi enviado pelo ExtJS. Esse start vai nos dizer qual é o primeiro registro a ser buscado no banco de dados.

Na linha 6 pegamos o parâmetro limit do request que foi enviado pelo ExtJS. Esse limit vai nos dizer qual é a quantidade máxima de registros a serem buscados no banco de dados.

Na linha 8 temos a declaração da consulta feita no MySQL – e é assim que vamos aplicar os parâmetros start e limit. Se você for usar outro banco de dados, precisa verificar a sintaxe correta. Nesse link tem um exemplo de como fazer paginação no Oracle, MS SQL Server e MySQL: http://thenitai.com/2009/11/15/sql-paging-with-oracle-mysql-and-ms-sql/

Nas linhas 10 a 17 fazemos a consulta e jogamos os resultados em um array.

Nas linhas 19 a 22 pegamos o total de registros que existem na tabela. O ExtJS precisa dessa informação para calcular a quantidade de páginas do grid.

E nas linhas 24 a 29 apenas formatamos a informação no formato JSON que o ExtJS está esperando.

3.3 – Criando um Contato

O objetivo do código é pegar os parâmetros enviados pelo ExtJS, fazer o INSERT no banco de dados e retornar os dados atualizados para o ExtJS – arquivo criaContato.php que está dentro do diretório php:

[code lang="php" firstline="1" toolbar="true" collapse="false" wraplines="false"]
<?php
//chama o arquivo de conexão com o bd
include("conectar.php");

$info = $_POST['contatos'];

$data = json_decode(stripslashes($info));

$nome = $data->name;
$email = $data->email;
$phone = $data->phone;

//consulta sql
$query = sprintf("INSERT INTO contact (name, email, phone) values ('%s', '%s', '%s')",
mysql_real_escape_string($nome),
mysql_real_escape_string($email),
mysql_real_escape_string($phone));

$rs = mysql_query($query);

echo json_encode(array(
"success" => mysql_errno() == 0,
"contatos" => array(
"id" => mysql_insert_id(),
"nome" => $nome,
"email" => $email,
"phone" => $phone
)
));
?>
[/code]

Na linha 5 pegamos as informações contidas dentro do parâmetro contatos (lembra que no Writer colocamos o root como contatos?) que foi enviado através de um método HTTP POST do ExtJS.

Nas linhas 9 a 11 apenas extraímos os dados que queremos que estavam encapsulados dentro do root contatos. Como é um contato novo, não precisamos pegar o id, pois o mesmo será fornecido pelo banco de dados.

Nas linhas 14 a 19 apenas executamos a query de INSERT.

Nas linhas 21 a 29 montamos o JSON de retorno. Precisamos enviar de volta o dado que acabamos de inserir na base, pois a Store do ExtJS vai marcar internamente que aquele registro é novo, e quando enviamos o retorno, a Store vai atualizar os dados (no caso teremos um id diferente de zero) e a Store vai marcar o registro como OK.  Assim, quando sincronizarmos novamente a Store por qualquer motivo, a Store não precisa enviar esse dado de novo.

3.4 – Atualizando um Contato

A lógica usada para atualizar um contato é bem parecida com a criar. O objetivo do código é pegar os parâmetros enviados pelo ExtJS, fazer o UPDATE  no banco de dados e retornar os dados atualizados para o ExtJS – arquivo atualizaContato.php que está dentro do diretório php:

[code lang="php" firstline="1" toolbar="true" collapse="false" wraplines="false"]
<?php
//chama o arquivo de conexão com o bd
include("conectar.php");

$info = $_POST['contatos'];

$data = json_decode(stripslashes($info));

$nome = $data->name;
$email = $data->email;
$phone = $data->phone;
$id = $data->id;

//consulta sql
$query = sprintf("UPDATE contact SET name = '%s', email = '%s', phone = '%s' WHERE id=%d",
mysql_real_escape_string($nome),
mysql_real_escape_string($email),
mysql_real_escape_string($phone),
mysql_real_escape_string($id));

$rs = mysql_query($query);

echo json_encode(array(
"success" => mysql_errno() == 0,
"contatos" => array(
"id" => $id,
"name" => $nome,
"email" => $email,
"phone" => $phone
)
));
?>
[/code]

Na linha 5 pegamos as informações contidas dentro do parâmetro contatos (lembra que no Writer colocamos o root como contatos?) que foi enviado através de um método HTTP POST do ExtJS.

Nas linhas 9 a 12 apenas extraímos os dados que queremos que estavam encapsulados dentro do root contatos. Como não é um contato novo, precisamos pegar o id, para fazer o filtro do UPDATE na base.

Nas linhas 15 a 21 apenas executamos a query de UPDATE.

E nas linhas 23 a 31 montamos o JSON de retorno. Da mesma forma que a Store sabe quando um registro é novo, ela também sabe que um registro foi atualizado e usa uma flag interna para isso. Quando retornamos o success e os dados atualizados, a Store vai atualizar os dados do registro e marcar que está OK.

3.5 – Excluindo um Contato

O objetivo do código é pegar os parâmetros enviados pelo ExtJS – nesse caso nos interessamos apenas pelo id, fazer o DELETE no banco de dados e retornar os dados atualizados para o ExtJS – arquivo deletaContato.php que está dentro do diretório php:

[code lang="php" firstline="1" toolbar="true" collapse="false" wraplines="false"]
<?php
//chama o arquivo de conexão com o bd
include("conectar.php");

$info = $_POST['contatos'];

$data = json_decode(stripslashes($info));

$id = $data->id;

//consulta sql
$query = sprintf("DELETE FROM contact WHERE id=%d",
mysql_real_escape_string($id));

$rs = mysql_query($query);

echo json_encode(array(
"success" => mysql_errno() == 0
));
?>
[/code]

Na linha 5 pegamos as informações contidas dentro do parâmetro contatos (lembra que no Writer colocamos o root como contatos?) que foi enviado através de um método HTTP POST do ExtJS.

Na linha 9 pegamos apenas o id, pois só estamos interessados nele.

Nas linhas 12 a 15 fazemos o DELETE no banco de dados.

E nas linhas 17 a 19 apenas retornamos success. Repare que para o UPDATE e INSERT precisamos retornar todos os dados do contato que foi enviado para o Server. No caso do DELETE, apenas precisamos retornar o success para avisar que o delete ocorreu com sucesso e nesse caso a Store vai completar a requisição e remover o registro.

Conclusão:

Bem pessoal, agora já temos toda a lógica do servidor pronta e todas as classes do ExtJS necessárias para fazer essa comunicação. No próximo post vamos começar a montar as Views.

Até o próximo post!