buscando_pelo_parametro - VWJavascript/Alurapic GitHub Wiki
Podemos ter acesso aos parâmetros da rota através do serviço ActivatedRoute. Que tal berrarmos para o framework solicitando esse serviço? Vamos fazer importar ActivatedRoute e indicá-lo como dependência em nossa classe CadastroComponent, fazendo com que o sistema de injeção de dependências do Angular injete-o para nós. Inclusive vamos adicionar a propriedade mensagem assim como fizemos em CadastroComponent para exibirmos notificações para o usuário:
// alurapic/client/app/cadastro/cadastro.component.ts
import { Component, Input } from '@angular/core';
import { FotoComponent } from '../foto/foto.component';
import { Http, Headers } from '@angular/http';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { FotoService } from '../foto/foto.service';
import { ActivatedRoute } from '@angular/router';
@Component({
moduleId: module.id,
selector: 'cadastro',
templateUrl: './cadastro.component.html'
})
export class CadastroComponent {
foto: FotoComponent = new FotoComponent();
service: FotoService;
meuForm: FormGroup;
route: ActivatedRoute; // nova propriedade
mensagem: string = ''; // nova propriedade
constructor(service: FotoService, fb: FormBuilder, route: ActivatedRoute) {
this.route = route;
// código posterior omitido
Vamos adicionar também aquela mensagem condicional, igualzinho ao que fizemos no template de ListagemComponent:
<!-- alurapic/client/app/cadastro/cadastro.component.html -->
<div class="container">
<h1 class="text-center">{{foto.titulo}}</h1>
<p *ngIf="mensagem.length" class="alert alert-info">{{mensagem}}</p>
<!-- código posterior omitido -->
Através da instância de ActivatedRoute obtermos o parâmetro passado da seguinte maneira:
import { Component, Input } from '@angular/core';
import { FotoComponent } from '../foto/foto.component';
import { Http, Headers } from '@angular/http';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { FotoService } from '../foto/foto.service';
import { ActivatedRoute } from '@angular/router';
@Component({
moduleId: module.id,
selector: 'cadastro',
templateUrl: './cadastro.component.html'
})
export class CadastroComponent {
foto: FotoComponent = new FotoComponent();
service: FotoService;
meuForm: FormGroup;
route: ActivatedRoute;
mensagem: string = '';
constructor(service: FotoService, fb: FormBuilder, route: ActivatedRoute) {
this.route = route;
this.service = service;
this.route.params.subscribe(params => console.log(params['id']));
// código posterior omitido
Vamos digitar no browser a URL localhost:3000/cadastro/10. Um olhar atento no console mostra que o ID que passamos como parâmetro para a URL é exibido. Perfeito, mas precisamos alterar o nosso routerLink que utilizamos na tag que envolve nossa foto. A ideia é que ao ser clicado, ele construa o endereço para nós levando em consideração o ID da foto:
<!-- alurapic/client/app/listagem/listagem.component.html -->
<div class="row">
<painel *ngFor="let foto of fotos | filtroPorTitulo: textoProcurado.value" titulo="{{foto.titulo | uppercase}}" class="col-md-2">
<a [routerLink]="['/cadastro', foto._id]">
<foto titulo="{{foto.titulo}}" url="{{foto.url}}"></foto>
</a>
<button class="btn btn-danger btn-block" (click)="remove(foto)">Remover</button>
</painel>
</div><!-- fim row -->
Agora, para cada foto clicada, seremos levados para CadastroComponent e este terá acesso ao ID da foto que clicamos. Precisamos agora buscar a foto no servidor.
Só podemos buscar a foto apenas se Cadastro recebeu o ID de alguma foto, claro. O código é muito parecido com o que já fizemos.
// alurapic/client/app/cadastro/cadastro.component.ts
import { Component, Input } from '@angular/core';
import { FotoComponent } from '../foto/foto.component';
import { Http, Headers } from '@angular/http';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { FotoService } from '../foto/foto.service';
import { ActivatedRoute } from '@angular/router';
@Component({
moduleId: module.id,
selector: 'cadastro',
templateUrl: './cadastro.component.html'
})
export class CadastroComponent {
foto: FotoComponent = new FotoComponent();
service: FotoService;
meuForm: FormGroup;
route: ActivatedRoute;
mensagem: string = '';
constructor(service: FotoService, fb: FormBuilder, route: ActivatedRoute) {
this.route = route;
this.service = service;
this.route.params.subscribe(params => {
let id = params['id'];
if(id) {
this.service.buscaPorId(id)
.subscribe(
foto => this.foto = foto,
erro => console.log(erro));
}
});
// código posterior omitido
Nosso código não compila porque o método buscaPorId ainda não existe em FotoService. Vamos criá-lo:
// código anterior omitido
// alurapic/client/app/foto/foto.service.ts
buscaPorId(id: string): Observable<FotoComponent> {
return this.http
.get(this.url + '/' + id)
.map(res => res.json());
}
// código posterior omitido
Pronto. Para cada foto que acessarmos em ListagemComponent, seus dados são exibidos em CadastroComponent. No entanto, podemos melhorar a legibilidade do nosso código. Para não deixar um monte de código perdido dentro do nosso construtor, vamos criar um método com um nome que deixa bem claro o que o código faz. Vamos chamá-lo de buscaPorId e fazer com que ele receba o ID da foto que desejamos buscar.