在 Angular 5 中呈现 Observable
Render Observable in Angular 5
我正在尝试在 Angular 中呈现 Observable。我正在向 API 发出请求以获取一些数据,但是当我尝试渲染它时,浏览器中没有显示任何内容。
这是 服务 我用来获取有关 1 个用户的数据:
export class UserService {
public _url: string = "https://url/rest/user/";
constructor(private http: HttpClient) { }
getUser(id): Observable<IUser>{
return this.http.get<IUser>(this._url + id)
.catch(this.errorHandler);
}
errorHandler(error: HttpErrorResponse){
return Observable.throw(error.message);
}
}
这是用户组件:
@Component({
selector: 'app-user',
templateUrl: './user.component.html',
providers: [ UserService ],
styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {
public userId;
public errorMsg;
user: IUser;
constructor(private route: ActivatedRoute, private _userService:
UserService) { }
ngOnInit() {
let id = parseInt(this.route.snapshot.paramMap.get('id'));
this.userId = id;
this._userService.getUser(this.userId)
.subscribe(data => this.user = data,
error => this.errorMsg = error);
}
}
我用来呈现 de User 的视图 HTML 是:
<div>
<h2>{{user?.firstName}} {{user?.lastName}}</h2>
<dl>
<dt>Age:</dt>
<dd>{{user?.age}}</dd>
<dt>ID:</dt>
<dd>{{user?.id}}</dd>
<dt>Email:</dt>
<dd>{{user?.email}}</dd>
</dl>
</div>
在这个例子中我没有错误,但是用户字段都是空的,没有显示任何内容。我试过使用这个:
<div *ngIf="user | async; let user; else loading">
<ng-template #loading>Loading User Data...</ng-template>
但是不行,控制台显示:
Error: InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe' ...
我在另一个组件中执行相同的过程,我在其中使用像 IUser[] 这样的用户数组,这次我使用 ngfor 显示数据并且一切正确,数据在浏览器中显示为预期..我正在按照上面解释的方式进行操作,但使用 ngif 或 user?.id 并且没有数组。
至于最后的错误,async
管道仅适用于可观察对象。因此,与其将数据保存在用户变量中,然后将其传递给异步管道,不如尝试保存可观察对象本身:const user$ = this._userService.getUser(this.userId)
,然后将其传递到 async
管道:{{ user$ | async }}
。
然后您可以像这样访问属性:{{ (user$ | async).age }}
等等。
对于您最初的错误,可能只是请求的问题。您可以尝试将 data
的值注销到订阅中的控制台以进行故障排除。也许您需要 data.response
或其他东西。 (您可以检查这一点的一种方法是使用我上面提到的可观察方法并在您的模板中执行 {{ user$ | async | json }}
以查看对 userService.get
的调用给您带来了什么。
请注意,虽然您可以使用手动订阅,但您需要自行清理订阅。 async
管道是解决此类问题的方法。
有关这方面的更多信息,请查看此处:https://angular.io/api/common/AsyncPipe
首先,您需要将@angular/http 的响应导入到您的服务中。
import { Http, Headers, Response } from "@angular/http";
并从 rx/js 映射:
import { map } from 'rxjs/operators';
然后,在您的服务中,尝试以下操作:
return this.http.get(this._url + id).pipe(
map((resp:Response) => resp.json())
)
这应该将您的回复映射到 JSON。订阅 observable 应该按照您现在在组件中的方式工作。
API returns 用户列表,而不是单个用户(即使您指示响应是 IUser
)
您需要做一些映射以仅获取第一个元素:
getUser(id): Observable<IUser> {
return this.http.get<IUser>(this._url + id).map(resp => resp[0])
.catch(this.errorHandler);
}
查看修改后的代码:https://angular-uqsks5.stackblitz.io
我正在尝试在 Angular 中呈现 Observable。我正在向 API 发出请求以获取一些数据,但是当我尝试渲染它时,浏览器中没有显示任何内容。
这是 服务 我用来获取有关 1 个用户的数据:
export class UserService {
public _url: string = "https://url/rest/user/";
constructor(private http: HttpClient) { }
getUser(id): Observable<IUser>{
return this.http.get<IUser>(this._url + id)
.catch(this.errorHandler);
}
errorHandler(error: HttpErrorResponse){
return Observable.throw(error.message);
}
}
这是用户组件:
@Component({
selector: 'app-user',
templateUrl: './user.component.html',
providers: [ UserService ],
styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {
public userId;
public errorMsg;
user: IUser;
constructor(private route: ActivatedRoute, private _userService:
UserService) { }
ngOnInit() {
let id = parseInt(this.route.snapshot.paramMap.get('id'));
this.userId = id;
this._userService.getUser(this.userId)
.subscribe(data => this.user = data,
error => this.errorMsg = error);
}
}
我用来呈现 de User 的视图 HTML 是:
<div>
<h2>{{user?.firstName}} {{user?.lastName}}</h2>
<dl>
<dt>Age:</dt>
<dd>{{user?.age}}</dd>
<dt>ID:</dt>
<dd>{{user?.id}}</dd>
<dt>Email:</dt>
<dd>{{user?.email}}</dd>
</dl>
</div>
在这个例子中我没有错误,但是用户字段都是空的,没有显示任何内容。我试过使用这个:
<div *ngIf="user | async; let user; else loading">
<ng-template #loading>Loading User Data...</ng-template>
但是不行,控制台显示:
Error: InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe' ...
我在另一个组件中执行相同的过程,我在其中使用像 IUser[] 这样的用户数组,这次我使用 ngfor 显示数据并且一切正确,数据在浏览器中显示为预期..我正在按照上面解释的方式进行操作,但使用 ngif 或 user?.id 并且没有数组。
至于最后的错误,async
管道仅适用于可观察对象。因此,与其将数据保存在用户变量中,然后将其传递给异步管道,不如尝试保存可观察对象本身:const user$ = this._userService.getUser(this.userId)
,然后将其传递到 async
管道:{{ user$ | async }}
。
然后您可以像这样访问属性:{{ (user$ | async).age }}
等等。
对于您最初的错误,可能只是请求的问题。您可以尝试将 data
的值注销到订阅中的控制台以进行故障排除。也许您需要 data.response
或其他东西。 (您可以检查这一点的一种方法是使用我上面提到的可观察方法并在您的模板中执行 {{ user$ | async | json }}
以查看对 userService.get
的调用给您带来了什么。
请注意,虽然您可以使用手动订阅,但您需要自行清理订阅。 async
管道是解决此类问题的方法。
有关这方面的更多信息,请查看此处:https://angular.io/api/common/AsyncPipe
首先,您需要将@angular/http 的响应导入到您的服务中。
import { Http, Headers, Response } from "@angular/http";
并从 rx/js 映射:
import { map } from 'rxjs/operators';
然后,在您的服务中,尝试以下操作:
return this.http.get(this._url + id).pipe(
map((resp:Response) => resp.json())
)
这应该将您的回复映射到 JSON。订阅 observable 应该按照您现在在组件中的方式工作。
API returns 用户列表,而不是单个用户(即使您指示响应是 IUser
)
您需要做一些映射以仅获取第一个元素:
getUser(id): Observable<IUser> {
return this.http.get<IUser>(this._url + id).map(resp => resp[0])
.catch(this.errorHandler);
}
查看修改后的代码:https://angular-uqsks5.stackblitz.io