Usando rotas em Angular 2
Há alguns dias vimos aqui no Clube dos Geeks uma postagem introdutória sobre Angular 2: Iniciando com Angular 2, e fizemos um pequeno exemplo.
Hoje faremos um exemplo de como usar rotas em Angular 2. Veja:
Downloads
A única coisa que vamos precisar baixar é o bootstrap.
Estrutura da aplicação
Nossa aplicação terá uma estrutura simples, contanto com components e views.
index.html
O arquivo principal da aplicação, que deve conter as configurações para uso do TypeScript com SystemJS, como visto no post TypeScript – executando no browser com SystemJS.
Este arquivo deve ficar da seguinte forma:
<!DOCTYPE html> <html> <head> <script>document.write('<base href="' + document.location + '" />');</script> <title>Angular2 Routing - Clube dos Geeks</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="bootstrap/css/bootstrap.css"> <!-- jQuery --> <script src="http://code.jquery.com/jquery-1.12.0.min.js"></script> <!-- Bootstrap --> <script src="bootstrap/js/bootstrap.js"></script> <!-- IE required polyfills, in this exact order --> <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.0/es6-shim.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.26/system-polyfills.js"></script> <script src="https://npmcdn.com/angular2@2.0.0-beta.17/es6/dev/src/testing/shims_for_IE.js"></script> <script src="https://code.angularjs.org/2.0.0-beta.17/angular2-polyfills.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.26/system.js"></script> <script src="https://npmcdn.com/typescript@1.8.10/lib/typescript.js"></script> <script src="https://code.angularjs.org/2.0.0-beta.17/Rx.js"></script> <script src="https://code.angularjs.org/2.0.0-beta.17/angular2.dev.js"></script> <script src="https://code.angularjs.org/2.0.0-beta.17/router.dev.js"></script> <script> System.config({ transpiler: 'typescript', typescriptOptions: { emitDecoratorMetadata: true }, packages: {'app': {defaultExtension: 'ts'}} }); System.import('app/main') .then(null, console.error.bind(console)); </script> </head> <body> <my-app>Loading...</my-app> </body> </html>
Preste atenção que na linha 24 desse arquivo é importado um arquivo JavaScript, o router.dev.js que é o que nos permite usar as rotas.
app/main.ts
Este arquivo inicia nossa aplicação Angular 2, usando o componente importado para isso. E usando aquilo que é chamado de bootstrapper que importado do angular.
import { bootstrap } from 'angular2/platform/browser'; import { AppComponent } from './app.component'; bootstrap(AppComponent);
Note que na linha 2 importamos o arquivo app.component que é o componente principal da nossa aplicação, onde faremos as rotas.
app/app.component.ts
Nosso componente principal, tem a função de controlar o html, criando nossa aplicação na tag informada como seletor.
import { Component } from 'angular2/core'; import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router'; import { provide } from 'angular2/core'; import { PessoaComponent } from './pessoa.component'; import { ProdutoComponent } from './produto.component'; @Component({ selector: 'my-app', templateUrl: 'views/index.html', directives: [ROUTER_DIRECTIVES], providers: [ROUTER_PROVIDERS] }) @RouteConfig([ { path: '/pessoas', name: 'Pessoas', component: PessoaComponent, useAsDefault: true }, { path: '/produtos', name: 'Produtos', component: ProdutoComponent } ]) export class AppComponent { }
Na linha 2 importamos os elementos necessários para configurar as rotas, isso é possível graças ao arquivo router.dev.js.
Usando @RouteConfig podemos configurar as rotas, veja que são configuradas duas, com os seguintes campos:
- path: É o caminho da rota estará na barra de endereço do navegador (
/pessoas
). - name: O nome oficial da rota; deve começar com uma letra maiúscula, para evitar confusão com o path (
Pessoas
). - component: o componente que deve ser criado ao navegar para essa rota (
PessoasComponent
).
Note que os componentes são importados de outros arquivos. São dois: um para Pessoas e outro para Produtos.
app/pessoa.component.ts
Um componente simples que controla uma view.
import {Component} from 'angular2/core'; @Component({ templateUrl: "views/pessoa.html" }) export class PessoaComponent { private pessoas: PessoaComponent[]; constructor() { this.pessoas = [ { id: 1, name:'Jayr', email:"jayr@clubedosgeeks.com.br"}, { id: 2, name: "teste", email: "teste@clubedosgeeks.com.br" } ]; } }
Note que o componente tem apenas uma classe com um atributo que é o array de pessoas sendo preenchido pelo construtor.
app/produto.component.ts
Da mesma forma está o componente para produtos.
import {Component} from 'angular2/core'; @Component({ templateUrl: "views/produto.html" }) export class ProdutoComponent { private produtos: ProdutoComponent[]; constructor() { this.produtos = [ { id: 1, name: 'Produto 1', price: "R$ 29,00" }, { id: 2, name: "Produto 2", price: "R$ 10,00" } ]; } }
view/index.html
Essa view será a principal da aplicação, mostrada pelo AppComponent contendo as referências às rotas e o campo de trabalho delas, ou seja onde as views das rotas serão mostradas. Veja:
<nav class="navbar navbar-default"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">Clube dos Geeks</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li><a [routerLink]="['Pessoas']">Pessoas</a></li> <li><a [routerLink]="['Produtos']">Produtos</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <div class="container"> <router-outlet></router-outlet> </div>
Note as referências às rotas usando a diretiva [routerLink] e tendo como referência os nomes das rotas definidos no AppComponent.
Note também a tag <router-outlet></router-outlet> , que é a saída da rota, exatamente onde serão mostradas as views das rotas.
views/pessoa.html
Temos uma view simples, apenas com o título e uma tabela com repetidor:
<h3>Pessoas</h3> <table class="table"> <thead> <tr> <th>#</th> <th>Nome</th> <th>E-mail</th> </tr> </thead> <tbody> <tr *ngFor="#pessoa of pessoas"> <td>{{pessoa.id}}</td> <td>{{pessoa.name}}</td> <td>{{pessoa.email}}</td> </tr> </tbody> </table>
views/produto.html
Da mesma forma na view de produtos.
<h3>Produtos</h3> <table class="table"> <thead> <tr> <th>#</th> <th>Nome</th> <th>Preço</th> </tr> </thead> <tbody> <tr *ngFor="#produto of produtos"> <td>{{produto.id}}</td> <td>{{produto.name}}</td> <td>{{produto.price}}</td> </tr> </tbody> </table>
Mais
Concluindo
Este é o segundo post da série sobre Angular2.
Fique ligado, no próximo veremos como usar um service com comunicação Http.
change private PessoasCompoment[] to Array