Angular 4 Pipes中的异步调用

时间:2017-08-28 12:33:26

标签: angular angular-pipe

我在服务上有一个方法,从服务器获取时间,我打算在自定义管道中使用它。管道的目的是将时间戳与当前时间进行比较,并以人类可读的格式返回。

服务

export class TimeService{
  currentServerTime;

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

        return this.currentServerTime;
     })
  }
}

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>

我坚持使用异步调用。只有在从服务器获取数据后,如何从管道返回值?

2 个答案:

答案 0 :(得分:5)

缺少return,需要更改subscribe map以允许异步管道进行订阅

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

对于异步值,需要使用异步管道

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

答案 1 :(得分:2)

实现它的最佳方法是不使用管道内的服务。 您可以使用自定义管道仅实现管道需要执行的操作。 您的管道需要像这样定义:

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);
            }
   }
}

在组件内部,您可以调用服务并将其存储在Oninit生命周期的变量中(当然,您需要在组件内部注入服务)。

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

然后在组件的模板中,您可以使用管道。

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

或者

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

澄清&amp;目的

此实施的目的是促进:

- 测试你的烟斗

- 如果服务器有问题,则进行简单的调试

- 来自服务器的独立实现,可以在具有不同参数(可重用性)的其他组件中使用。