[英]Angular2 Notify Component Of Data Change
因此,我一直在研究Angular 2教程和文檔。 在試用它時,我想看看是否可以將表單分成其自己的組件,但仍以相同的方式工作。 當您添加英雄時,它會自動將其添加到列表中。 我將列表作為父組件,並將表單作為子組件。 目前,當您添加英雄時,它會添加到數據中,但列表不會自動更新。 但是,如果您導航到儀表板然后返回列表,則英雄現在就在那里。
這是我的清單組件:
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Hero } from './hero';
import { HeroFormComponent } from './hero-form.component';
import { HeroService } from './hero.service';
@Component({
selector: 'my-heroes',
templateUrl:'app/heroes.component.html',
styleUrls: ['app/heroes.component.css'],
providers: [HeroService],
directives: [HeroFormComponent]
})
export class HeroesComponent implements OnInit {
heroes: Hero[];
selectedHero: Hero;
constructor(private router: Router, private heroService: HeroService) {}
delete(hero: Hero): void {
this.heroService
.delete(hero.id)
.then(() => {
this.heroes = this.heroes.filter(h => h !== hero);
if(this.selectedHero === hero) { this.selectedHero = null; }
});
}
getHeroes(): void {
this.heroService.getHeroes().then(heroes => this.heroes = heroes);
}
ngOnInit(): void {
this.getHeroes();
}
onSelect(hero: Hero): void {
if(this.selectedHero === hero) {
this.selectedHero = null;
} else {
this.selectedHero = hero;
}
}
gotoDetail(): void {
this.router.navigate(['/detail', this.selectedHero.id]);
}
}
這是我的表單組件:
import { Component, Injectable } from '@angular/core';
import { Hero } from './hero';
import { HeroService } from './hero.service';
import { HeroesComponent } from './heroes.component';
@Component({
selector: 'hero-form',
templateUrl: 'app/hero-form.component.html',
providers: [HeroService]
})
@Injectable()
export class HeroFormComponent {
heroes: Hero[] = [];
constructor(private heroService: HeroService) {}
add(name: string, heroName: HTMLInputElement): void {
name = name.trim();
if (!name) { return; }
this.heroService.create(name)
.then(hero => {
this.heroes.push(hero);
this.selectedHero = null;
});
heroName.value = null;
}
}
這是我的服務:
import { Injectable } from '@angular/core';
import { Headers, Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { Hero } from './hero';
@Injectable()
export class HeroService {
private heroesUrl = 'app/heroes';
private headers = new Headers({'Content-Type': 'application/json'});
constructor(private http: Http) { }
create(name: string): Promise<Hero> {
return this.http
.post(this.heroesUrl, JSON.stringify({name: name}), {headers: this.headers})
.toPromise()
.then(res => res.json().data)
.catch(this.handleError);
}
delete(id: number): Promise<void> {
let url = `${this.heroesUrl}/${id}`;
return this.http.delete(url, {headers: this.headers})
.toPromise()
.then(() => null)
.catch(this.handleError);
}
getHero(id: number): Promise<Hero> {
return this.getHeroes()
.then(heroes => heroes.find(hero => hero.id === id));
}
getHeroes(): Promise<Hero[]> {
return this.http.get(this.heroesUrl)
.toPromise()
.then(response => response.json().data as Hero[])
.catch(this.handleError);
}
update(hero: Hero): Promise<Hero> {
const url = `${this.heroesUrl}/${hero.id}`;
return this.http
.put(url, JSON.stringify(hero), {headers: this.headers})
.toPromise()
.then(() => hero)
.catch(this.handleError);
}
private handleError(error: any): Promise<any> {
console.error('An error occurred', error);
return Promise.reject(error.message || error);
}
}
為了使列表組件識別數據更新並刷新實際列表,需要做什么?
沒有將服務器上存在的Heros與客戶端上存在的Heros綁定的關系,因此,當服務器上的內容發生更改時(使用表單添加它們時),它將與客戶端上的列表不同步。 當您重新導航至HeroesComponent時,它們會暫時恢復同步,因為您再次調用了getHeroes()。 您需要一種方法來通知HeroesComponent有關數據的更改。
您當前正在使用Promises進行異步通信,但這還不夠好,因為Promises是一勞永逸的,而您需要連續更新,最好從服務中推送。 為此,您需要“可觀察”。 您可以在HeroesComponent ngOnInit()中注冊為該服務的英雄的觀察者,並在ngOnDestroy()中注銷。 調用getHeroes()時,該服務將需要發送英雄列表,但是當添加,刪除或編輯英雄時,該服務也需要重新發送。
問題是您正在解決英雄,因此不會反映任何進一步的更新,
服務
heroes: Subject<Hero[]> = new Subject<Hero[]>();
getHeroes(){
this.http.get(this.heroesUrl)
.toPromise()
.then(response => {
this.heroes.next(response.json().data as Hero[]);
})
.catch(this.handleError);
}
create(name: string): Promise<Hero> {
return this.http
.post(this.heroesUrl, JSON.stringify({name: name}), {headers: this.headers})
.toPromise()
.then(res => {
// update heroes observable
this.getHeroes();
return res.json().data
})
.catch(this.handleError);
}
英雄組成
getHeroes(): void {
this.heroes = this.heroService.heroes;
this.heroService.getHeroes();
}
在HTML模板中添加一個async
管道,這將有助於解決Promise,並將更新列表以供將來更新。
希望這可以幫助!!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.