簡體   English   中英

使異步管道更新Angular 2中的視圖

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM