Angular 4 个管道中的异步调用
Asynchronous calls in Angular 4 Pipes
我有一个服务方法可以从服务器获取时间,我打算在自定义管道中使用它。管道的目的是将时间戳与当前时间进行比较,并且 return 它采用人类可读的格式。
服务
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>
我被异步调用困住了。如何仅在从服务器获取数据后才 return 来自管道的值?
缺少 return
,需要更改 subscribe
map
以允许异步管道执行订阅
return this.timeService.fetchCurrentTimestamp().map(data => {
对于异步值,需要使用异步管道
<span>{{model.created | getTimeFromNow | async }}</span>
最好的实现方式是不使用管道内的服务。
您可以使用自定义管道来仅实现管道需要执行的操作。
您的管道需要这样定义:
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>
说明与目的:
此实施的目的是促进:
-正在测试您的管道
-如果服务器有问题,轻松调试
-来自服务器的独立实现,可以在具有不同参数的其他组件中使用(可重用性)。
我有一个服务方法可以从服务器获取时间,我打算在自定义管道中使用它。管道的目的是将时间戳与当前时间进行比较,并且 return 它采用人类可读的格式。
服务
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>
我被异步调用困住了。如何仅在从服务器获取数据后才 return 来自管道的值?
缺少 return
,需要更改 subscribe
map
以允许异步管道执行订阅
return this.timeService.fetchCurrentTimestamp().map(data => {
对于异步值,需要使用异步管道
<span>{{model.created | getTimeFromNow | async }}</span>
最好的实现方式是不使用管道内的服务。 您可以使用自定义管道来仅实现管道需要执行的操作。 您的管道需要这样定义:
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>
说明与目的:
此实施的目的是促进:
-正在测试您的管道
-如果服务器有问题,轻松调试
-来自服务器的独立实现,可以在具有不同参数的其他组件中使用(可重用性)。