segunda-feira, 23 de dezembro de 2013

REST - Aula Prática - Alterar os Dados (Parte 1)

Optei por dividir a alteração por ser um tanto complexa (nada para morrer de susto). Nesta primeira parte, chamamos o formulário com o livro selecionado. Não pretendo me repetir deste modo, recomendo que veja a postagem anterior para tirar qualquer dúvida sobre qual arquivo modificar (que serão os mesmos e na mesma sequência).

Mudar a Camada de Visão


Adicionamos um botão na tela da listagem dos dados (abaixo do botão de Novo), na página que produz a listagem dos livros:
    ...
    <div class="btn-group" ng-hide="nome == ''">
     <a class="btn btn-large" href="/editar/{{nome}}">Editar</a>
    </div>
    ...
Este botão somente é visível ao selecionarmos um livro da listagem. Existe um evento ng-click="select(livro)" na tag "tr", que na Controller desta página, dispara a função select que atribui a variável $scope.nome a descrição do livro selecionado. Nosso próximo passo consiste em criar um formulário chamado quando o caminho editar for executado. Na pasta \views criamos a página editar.html com a seguinte codificação:
<!doctype html>
<html>
 <head>
  <meta Charest="UTF-8">
  <title>Teste AngularJS/NodeJS</title>
  <link rel="stylesheet" type="text/css" href="/css/bootstrap.css">
  <script src="/js/angular.min.js"></script>
  <script src="/js/controllers.js"></script>
 </head>
 <body ng-app ng-controller="EditarCtrl">
  <div class="container">
   <h2>Livro Selecionado</h2>
   <form ng-model="livro" name="livroform" class="form-horizontal">
    <div>
     <label for="nome" class="label" style="margin-right:6px;">Nome:</label>
     <input id="nome" placeholder="{{livro.nome}}" ng-model="livro.nome" />
    </div>
    <br />
    <div>
     <label for="autor" class="label" style="margin-right:6px;">Autor(es):</label>
     <input id="autor" placeholder="{{livro.autor}}" ng-model="livro.autor" />
    </div>
    <div class="form-actions">
     <button ng-click="modificar()" class="btn btn-primary">Modificar</button>
     <a href="/" class="btn">Voltar</a>
    </div>    
   </form> 
  </div>
 </body>
</html>
É quase uma cópia do formulário para a inserção do livro, alguns desenvolvedores optam por um único formulário e procedem as mudanças dinamicamente. Para não complicar demais, preferi deixá-los separados. Adicionamos a seguinte função no arquivo controller.js que responde a este formulário:
function EditarCtrl ($scope, $http) {
  $scope._id = 0;
  $scope.livro = {};
  var caminho = document.URL;
  caminho = caminho.substring(caminho.lastIndexOf('/'));
  $http.get('/lista/livro' + caminho).success(function(data) {
    $scope._id = data[0]._id;
    $scope.livro.nome = data[0].nome;
    $scope.livro.autor = data[0].autor;
  })
}
Da mesma forma que fizemos para listarmos vários livros, executamos uma função do banco que retorna (de modo Json) o registro selecionado.

Mudar a Camada de Dados


Necessitamos criar uma função para retornar um determinado livro. No arquivo de funções do banco, inserimos a seguinte função (abaixo da função gravar):
exports.procurar = function (req, res) {
  livroModel.find({nome: req.params.nom}).exec(function(err, livro) {
    if (err) { return console.log(err); }
    return res.json(livro);
  });
}
Não vamos brincar com ID's (que será utilizado somente no momento de proceder a alteração). Neste momento, poderíamos até passar a ObjectID, entretanto isso ficaria bem estranho no caminho URL (outras das pequenas regras de REST - Caminhos reconhecíveis pelo usuário), aqui trafegamos somente o que o usuário reconhece que é o nome. A função find localiza registros por qualquer parâmetro passado (é como um SELECT de SQL), vejamos alguns exemplos:

  • find({idade:{$gt:18}}) - Registros que possuem o campo idade maior que 18
  • find({valor:{$gt:50,$lt:100}}) - Registros que possuem o campo valor maior que 50 e menor que 100
  • find({editora :'OReilly'}).where('valor').gt(50).lt(100) - Registros que possuem o campo editora com o valor 'OReilly' e o campo valor maior que 50 e menor que 100
  • find({editora :'OReilly'}).limit(2)- Os dois primeiros registros que possuem o campo editora com o valor 'OReilly'
Acredito que já deu para sentir o que podemos produzir com a função "find".

Mudar a Camada do Servidor


No arquivo do servidor adicionamos duas novas rotas para chamar a tela e outra para disparar a função do banco criada, ambas recebem o parâmetro "nom":
app.get('/editar/:nom', routes.editar);
app.get('/lista/livro/:nom', livro.procurar);
E finalizamos com a adição do caminho para chamar a tela no arquivo de rotas:
exports.editar = function(req, res) {
  fs.readFile('../views/editar.html', function(error, content) {
    if (error) {
      res.writeHead(500);
      res.end();
    } else {
      res.writeHead(200, { 'Content-Type': 'text/html' });
      res.end(content, 'utf-8');
    }
  });
};
O que acontece? O usuário seleciona um determinado registro da listagem e em seguida pressiona o botão Editar, este dispara a rota "/editar/nome" que chama o formulário. Através da "Controller" uma nova rota é disparada a "/lista/livro/nome" que executa a função procurar e fornece uma página Json com o registro selecionado, este é carregado para a variável $scope.livro e mostrado na página. Na próxima continuamos nosso CRUD com a segunda parte da modificação dos dados na tabela.

Obrigado e até a próxima
Fernando Anselmo

0 comentários:

Postar um comentário