2 votes

Détection des changements en Angulaire avec Observable timer

Le contexte :

J'ai un certain nombre de composants dans mon application Angular 6 qui doivent afficher l'heure actuelle (hh:mm).

Ceux-ci ont été initialement mis en œuvre en utilisant setInterval avec this.now qui sont liés dans la vue :

setInterval(() => {
   this.now = new Date();
}, 1000);

Naturellement, cela entraîne une détection des changements toutes les secondes, ce qui est un gaspillage étant donné que la valeur ne sera mise à jour qu'une fois par minute. Je peux améliorer cela en exécutant la fonction setInterval à l'extérieur de ngZone et déclencher manuellement la détection de changement si la minute est écoulée.

Question :

J'essaie d'implémenter un flux observable de dates qui émet une nouvelle valeur toutes les minutes. Voici ce que j'ai fait jusqu'à présent...

timer(0, 1000)
  .pipe(
    map(() => new Date()),
    distinctUntilChanged((a: Date, b: Date) => a.getMinutes() === b.getMinutes()),
    tap(date => console.log(date))
  );

Une nouvelle date est émise une fois par minute, mais l'abonnement à ce flux entraîne la détection des changements par Angular toutes les secondes. (J'ai confirmé cela en ajoutant un ngDoCheck à un composant qui s'y abonne).

Comment puis-je différer la détection des changements pour qu'elle ne se produise que lorsqu'une nouvelle valeur est émise ?

0voto

CruelEngine Points 1173

Vous pouvez utiliser un sujet et un intervalle pour cela, je suppose que cela peut se faire de cette manière :

Fondamentalement, dans votre code où vous avez implémenté ceci (en supposant que c'est un service séparé) : some.service.ts ) , définissez un sujet comme ceci :

someSubject : Subject<Date> = new Subject<Date>();

interval(1000)
  .pipe(
    map(() => new Date()),
    distinctUntilChanged((a: Date, b: Date) => a.getMinutes() === b.getMinutes()),
    tap(date => {
       console.log(date);
       this.someSubject.next(date);
       });
  ).subscribe();

S'abonner à la someSubject de l'endroit où vous voulez écouter le changement de date comme ceci :

this._someService.someSubject.subscribe((date : Date) =>{
 console.log(date); //you'll have a new date object everytime your date object changes i.e everyminute
});

n'oubliez pas d'importer interval de rxjs

J'ai créé un exemple (écouter un changement sur deux) en utilisant StackBlitz : https://stackblitz.com/edit/angular-4ytdbs

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X