2017-08-28 3 views
1

J'ai une méthode sur un service qui récupère l'heure du serveur et je prévois de l'utiliser dans un tube personnalisé. Le but du tube est de comparer l'horodatage à l'heure actuelle et de le renvoyer dans un format lisible par l'homme.Appels asynchrones dans Angular 4 Pipes

service

export class TimeService{ 
    currentServerTime; 

    fetchCurrentTimeStamp(){ 
    //http request using Observable 
    return sendGETRequest(.....).map(data => { 
     this.currentServerTime = data; 

     return this.currentServerTime; 
    }) 
    } 
} 

pipe

export class GetTimeFromNowPipe implements PipeTransform{ 

    fromNow; 
    currentServerTime: number; 
    constructor(private timeService: TimeService, private appSettings: AppSettings){} 

    transform(value: number){ 
     var currentTime; 
     this.timeService.fetchCurrentTimestamp().subscribe(data => { 
      currentTime = data 
      if(!value) return ""; 

      if(value){ 
       let newDate = moment.unix(value); 
       this.fromNow = newDate.from(moment.unix(currentTime), true); 
      } 
      return this.fromNow; 
     }); 

    } 
} 

HTML

<ul> 
    <li *ngFor = "let model of models"> 
     <span>{{model.created | getTimeFromNow}}</span> 
    </li> 
</ul> 

Je suis coincé avec les appels Async . Comment est-ce que je renvoie la valeur du tuyau seulement après que j'obtiens les données du serveur?

Répondre

3

Un return manque et subscribe a besoin d'être changé map pour permettre la conduite de async faire l'abonnement

return this.timeService.fetchCurrentTimestamp().map(data => { 

et async valeurs du tuyau async doit être utilisé

<span>{{model.created | getTimeFromNow | async }}</span> 
0

Le La meilleure façon de l'implémenter est de ne pas utiliser le service à l'intérieur du tuyau. Vous pouvez utiliser un canal personnalisé pour implémenter uniquement ce que le canal doit faire. Votre conduite doit être défini comme ceci:

export class GetTimeFromNowPipe implements PipeTransform{ 

    constructor(private appSettings: AppSettings){} 

    transform(value: number, currentTime:number){ 
      if(!value) return ""; 
      else{ 
       let newDate = moment.unix(value); 
       return newDate.from(moment.unix(currentTime), true); 
      } 
    } 
} 

à l'intérieur de votre appareil, vous pouvez appeler votre service et le stocker dans un varible dans votre cycle de vie onInit (bien sûr, vous devez injecter le service à l'intérieur du composant).

serverTime:number; 
ngOnInit(){ 
    this.timeService.fetchCurrentTimestamp().subscribe(data=>this.serverTime=data); 
    } 

puis à l'intérieur du modèle de votre composant, vous pouvez utiliser votre tuyau. soit

<ul *ngIf="serverTime"> 
    <li *ngFor = "let model of models"> 
     <span>{{model.created | getTimeFromNow:serverTime}}</span> 
    </li> 
</ul> 

Ou

<ul> 
    <li *ngFor = "let model of models"> 
     <span>{{model.created | getTimeFromNow: serverTime | async}}</span> 
    </li> 
</ul> 

Précision & fins:

le but de cette mise en œuvre est de faciliter:

-Test votre pipe

-easy débogage dans le cas où le serveur a des problèmes

-une implémentation indépendante du serveur qui peut être utilisée dans un autre composant avec des paramètres différents (réutilisabilité).