Na postagem anterior vimos como colocar os dados no
MongoDB, só que ao rever os arquivos anteriores descobri que deixei algumas coisas um tanto mal organizadas (o que pode prejudicar lá na frente) então permita-me nesta postagem arrumar o projeto para finalizarmos nosso CRUD.
Qual editor utilizar?
Essa é uma dúvida que muitas pessoas me fazem. Qualquer um serve entre o
NotePad++ ao
Eclipse, prefiro usar um editor intermediário, como o
Free JavaScript Editor que possui inclusive
autocomplete de código. O mais famoso deles se chama
Sublime Text, muitos professores que usam
Mac o utilizam, existem versões para Windows e Linux também, só que o preço da licença (70 dólares) chega a assustar muitas pessoas.
Arrumar a Camada do Servidor
Trocamos o nome do arquivo do servidor para
server.js e o colocamos na pasta
\server, com a seguinte codificação:
if (!process.env.NODE_ENV) process.env.NODE_ENV='development'
var express = require('express'),
routes = require('../routes'),
livro = require('../dados/livroFuncoes.js');
var app = module.exports = express.createServer();
app.configure(function(){
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use('/css', express.static(__dirname + './../public/stylesheets'));
app.use('/js', express.static(__dirname + './../public/javascripts'));
});
// Ambientes
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
// Rotas do Sistema
app.get('/', routes.index);
app.get('/lista/livro', livro.listar);
// Ativar o Servidor
app.listen(3000);
console.log("Servidor está executando na porta %d em modo de %s", app.address().port, app.settings.env);
Na primeira linha, definimos o modo que o servidor é iniciado em
development (desenvolvimento) ou
production (produção), veja na seção
ambientes as diferenças (aqui basicamente se mostrará ou não uma trilha de erro completa). Em seguida vemos as bibliotecas de uso e a configuração do servidor. O caminho das rotas de acesso e o inicio do servidor na porta 3000.
Para completar a definição desses caminhos, na pasta
\routes existe por padrão um arquivo chamado
index.js, devemos deixá-lo com a seguinte codificação:
var fs = require('fs');
exports.index = function(req, res){
fs.readFile('../views/index.html', function(error, content) {
if (error) {
res.writeHead(500);
res.end();
} else {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(content, 'utf-8');
}
});
};
Este arquivo contém os caminhos (as rotas) do sistema, e indica qual arquivo é chamado, no servidor deixamos apenas as indicação dos caminhos para este arquivo.
Arrumar a Camada de Dados
Agora vamos organizar os arquivos que fazem a comunicação com o banco
MongoDB. Na pasta principal
\app criamos uma pasta chamada
\dados e adicionamos o arquivo
livroFuncoes.js com a seguinte codificação:
banco = require('./livroDb.js'),
exports.listar = function (req, res){
livroModel.find().exec(function(err, livro) {
if (err) { return console.log(err); }
return res.json(livro);
});
}
Este arquivo é responsável por todas as funções de acesso a tabela (em breve teremos a inclusão, alteração, exclusão), neste momento, possui uma única função que retorna uma listagem dos dados do arquivo em formato Json. Criamos, também nesta pasta, um arquivo chamado
livroDb.js com a seguinte codificação:
mongoose = require('mongoose');
// Conexão com o Banco
mongoose.connect('mongodb://localhost:27017/livro');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function calbckcallback() {
init();
});
function init() {
schema = new mongoose.Schema({
nome: {type: String, unique: true},
autor: String
});
livroModel = mongoose.model('Livro', schema);
}
Este era o nosso antigo arquivo
db.js. Aqui temos uma conexão com o banco e a função
init() que determina como é a estrutura da tabela.
Arrumar a Camada de Visão
Copiamos todo o conteúdo da pasta
\sist para a pasta
\views. Nesta pasta
\views:
- Copiamos o arquivo \css\bootstrap.css para a pasta \public\stylesheets e eliminamos a pasta \css.
- Copiamos os arquivos \javascript\controllers.js, \lib\angular.min.js e \lib\angular.min.js.map para a pasta \public\javascripts e eliminamos as pastas \javascript e \lib.
Na pasta
\views criamos o arquivo
index.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="ListaCtrl">
<div class="container">
<h2>Meus Livros</h2>
<label for="criteria" class="label" style="margin-right:6px;">Pesquisar</label>
<input id="criteria" type="search" ng-model="criteria">
<table class="table table-striped table-hover table-bordered">
<thead>
<th>Título</th>
<th>Autor(es)</th>
</thead>
<tr ng-repeat="livro in livros | filter:criteria | orderBy:'nome'"
ng-click="select(livro)" ng-class="{'info': nome == livro.nome}">
<td>{{livro.nome}}</td>
<td>{{livro.autor | uppercase}}</td>
</tr>
</table>
</div>
</body>
</html>
Mostramos uma listagem principal dos dados conforme vimos anteriormente no arquivo
hello.html. Preferi republicá-lo neste outro arquivo para completarmos nossa padronização da codificação e não restar mais nenhuma dúvida. O próximo arquivo fica na pasta
\views\javascript, é o arquivo
controllers.js e possui a seguinte codificação:
function ListaCtrl($scope, $http) {
$scope.nome = '';
$http.get('/lista/livro').success(function(data) {
$scope.livros = data;
})
$scope.select = function(livro) {
$scope.nome = livro.nome;
}
}
Esta função acessa o
Json e obtém os dados para carregar a variável
$scope.livros para o preenchimento da tabela. A função
select será utilizada quando na seleção de um registro (para as funções de alteração e exclusão).
Nossa estrutura final ficou com o seguinte formato:
/app - Pasta raiz do projeto
/dados - Camada de Dados
livroDB.js - Acesso ao MongoDB
livroFuncoes.js - Funções da tabela "livros"
/public
/images - imagens do projeto
/javascripts - bibliotecas e controllers
angular.min.js - Biblioteca do AngularJS
angular.min.js.map - Mapeamento do AngularJS
controllers - Arquivo de Controller para o AngularJS
/stylesheets
bootstrap.css - Arquivo de estilos do Bootstrap
style.css - Arquivo de estilos criado por padrão
/routes
index.js - Contém as rotas do sistema
/server - Camada do Servidor
server.js - Inicia o servidor (na linha de comando: supervisor server.js)
/views - Camada de Visão
index.html - Janela principal do sistema
A única pasta que está faltando é a
\node_modules que são os módulos utilizados como:
express,
mongoose e
supervisor. Essa organização foi necessária para podermos continuar com nossos estudos.
Com esta implementação podemos ver os dados que foram inseridos no banco (ou seja, concluímos a letra
R), na próxima postagem continuaremos nosso CRUD com a inserção dos dados na tabela.
Obrigado e até a próxima
Fernando Anselmo