Angular 6如何异步更新列表信息?
本人前端萌新,学习过一点点Angular,然后自己写了一个简单例子,就是显示一下浏览器信息,相关代码如下,可以正常运行,界面会先显示浏览器的信息,然后过几秒显示出IP地址。
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import platform from 'platform';
import 'rxjs/add/operator/toPromise';
@Injectable()
export class ClientInfoService {
private static ipUrl = 'http://httpbin.org/ip';
constructor(private httpClient: HttpClient) {
}
getClientInfo(): Promise<ClientInfo[]> {
return new Promise((resolve, reject) => {
const clientInfo: ClientInfo[] = [];
clientInfo.push({key: '操作系统', value: `${platform.os}`});
clientInfo.push({key: '浏览器', value: `${platform.name} ${platform.version}`});
clientInfo.push({key: '用户代理', value: platform.ua});
this.httpClient.get(ClientInfoService.ipUrl)
.subscribe(data => {
clientInfo.push({key: 'IP地址', value: data['origin']});
resolve(clientInfo);
}, err => {
reject(err);
});
});
}
}
export interface ClientInfo {
key: string;
value: string;
}
然后Angular更新到6了,我研究一段时间以后,尝试升级了一下,好不容易代码能运行了,但是这下IP地址无法更新了。代码现在如下,程序其他部分也作了相应修改,可以编译。但是现在程序可以显示浏览器的信息,IP地址永远为空。我想了想,感觉问题应该是出在rxjs这里,因为我对这些概念不太理解,代码肯定写错了,所以希望高手们给我解解惑。感谢各位!
@Injectable()
export class ClientInfoService {
private static ipUrl = 'http://httpbin.org/ip';
constructor(private httpClient: HttpClient) {
}
getClientInfo(): Observable<ClientInfo[]> {
const clientInfo: ClientInfo[] = [];
clientInfo.push({key: '操作系统', value: `${platform.os}`});
clientInfo.push({key: '浏览器', value: `${platform.name} ${platform.version}`});
clientInfo.push({key: '用户代理', value: platform.ua});
const data = this.httpClient.get(ClientInfoService.ipUrl)
.pipe(
catchError(this.handleError('获取IP地址', '网络错误'))
);
clientInfo.push({key: 'IP地址', value: data['origin']});
return of(clientInfo);
}
private handleError<T>(operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
console.error(error);
return of(result as T);
};
}
}
export interface ClientInfo {
key: string;
value: string;
}
感谢各位的解答,现在终于可以显示IP地址了,但是还有一个问题就是原来是立即显示一些东西,然后获取到IP地址之后才更新。现在我这个代码变成了需要等到IP地址拿到之后才整个显示数据。请问这下应该如何处理?
getClientInfo(): Observable<ClientInfo[]> {
const clientInfo: ClientInfo[] = [];
clientInfo.push({key: '操作系统', value: `${platform.os}`});
clientInfo.push({key: '浏览器', value: `${platform.name} ${platform.version}`});
clientInfo.push({key: '用户代理', value: platform.ua});
return this.httpClient.get(ClientInfoService.ipUrl)
.pipe(
map(data => data['origin']),
catchError(this.handleError('获取IP地址', '网络错误')),
map(e => {
clientInfo.push({key: 'IP地址', value: e});
return clientInfo;
})
);
}
感觉我描述的不够清晰,顺便补上视图显示的代码。
@Component({
template: `
<mat-table #table [dataSource]="dataSource">
<ng-container matColumnDef="key">
<mat-header-cell *matHeaderCellDef>项目</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.key}}</mat-cell>
</ng-container>
<ng-container matColumnDef="value">
<mat-header-cell *matHeaderCellDef>值</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.value}}</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
`,
})
export class ClientInfoComponent implements OnInit {
dataSource: ClientInfoDataSource;
displayedColumns = ['key', 'value'];
constructor(private clientInfoService: ClientInfoService) {
}
ngOnInit(): void {
this.dataSource = new ClientInfoDataSource(this.clientInfoService);
}
}
class ClientInfoDataSource implements DataSource<any> {
constructor(private clientInfoService: ClientInfoService) {
}
connect(): Observable<ClientInfo[]> {
return this.clientInfoService.getClientInfo();
}
disconnect(): void {
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
rxjs 需要订阅,而上面这段代码中
this.httpClient.get
并未subscribe,也就不会触发,或者即使订阅了也因为是异步执行而没有效果,最终直接返回了值为clientInfo
的observer,这个值始终都会是[]
。正确做法
getClientInfo()
应该返回代码中定义的data
这个Observable
,比如说:好好看官方文档老铁