[英]Make the async pipe update the view in Angular 2
初始化后,下面看到的組件將在模板中顯示事件列表( ngOnInit()
)。 但是,當調用addEvent()
,該視圖將不會更新。 為什么會這樣呢?
每當我將新數據發布到用於填充observable屬性( events: Observable<Event[]>
)的數據存儲中時,如何使視圖更新?
@Component({
template:
<ul>
<li *ngFor="let event of events | async"
{{ event.title }}
</li>
</ul>
<button (click)="addEvent()">Add event</button>
})
export class EventCenterListComponent implements OnInit {
events: Observable<Event[]>;
constructor(
private eventsService: EventsService,
) {}
ngOnInit() {
this.events = return this.eventsService.getEvents();
}
addEvent() {
this.eventsService.createEvent('New event'); <--this would add one event to the data source
this.events = this.eventsService.getEvents(); <-- that reassignment would not be seen in the template
}
}
我已經看到很多教程,包括Angulat的官方教程,都將Observable轉換為純數組,然后push
新值push
入數組,例如:
heroes: Hero[];
addHero(name: string) {
this.heroService.create(name)
.subscribe(
hero => this.heroes.push(hero), <-- that would work
error => this.errorMessage = <any>error);
}
但是以上真的必要嗎? 我不能直接對可觀察對象進行操作並更新視圖嗎?
是的,最好不要訂閱該組件。
這是一個主意。 事件服務保留事件的私有數組,並在每次更改主題時觸發它。 該組件可以使用異步管道,以便在觸發該主題時更新其視圖。
@Injectable()
export class EventsService {
private events: Event[] = [];
private eventsSubject = new Subject<Event[]>();
private _events$ = this.eventsSubject.asObservable();
createEvent(title: string) {
const newEvent: Event = {title};
this.events = [...this.events, newEvent];
this.eventsSubject.next(this.events);
}
getEvents$() {
return this._events$;
}
}
@Component({
template: `
<ul>
<li *ngFor="let event of events | async">{{ event.title }}</li>
</ul>
<button (click)="addEvent()">Add event</button>`
})
export class EventCenterListComponent {
events: Observable<Event[]>;
constructor(private eventsService: EventsService) {
this.events = eventsService.getEvents$();
}
addEvent() {
this.eventsService.createEvent('New event');
}
}
更新
通過仔細閱讀您的問題獲得新思路。 假設EventService的工作方式如下:
createEvent(title: string): Observable<void> // post one new event to server
getEvents(): Observable<Event[]> // get list of events from server
...並且您只是想在發布新事件后重新獲取事件列表,然后實現如下的EventCenterListComponent:
export class EventCenterListComponent {
events: Observable<Event[]>;
private newEventSubject = new Subject<string>();
constructor(eventsService: EventsService) {
const eventWasCreated$ = this.newEventSubject.mergeMap(title =>
eventsService.createEvent(title));
const shouldRefresh$ = eventWasCreated$.startWith(undefined);
this.events = shouldRefresh$.switchMap(() =>
eventsService.getEvents());
// optional, if you are going to subscribe to `events` in more
// than one place:
this.events = this.events.share();
}
addEvent() {
this.newEventSubject.next('New event');
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.