我使用rx / js Observable调用JSON文件。
服务
constructor(private http: Http){
}
getUserById():Observable<User[]> {
let url = this.mockData;
let header = new Headers({'Content-Type': 'application/json'});
return this.http.get(url)
.map((res:Response) =><User[]>res.json())
.do(data => console.log("User Data: "+JSON.stringify(data)))
.catch((error:any) => Observable.throw(error) || "Mock Data Error get by role")
};
成分:
@Input() users: User[] = [];
userTemp: User[] = [];
getUserById(userId){
this._searchService.getUserById()
.filter(users => {
for(let user of users){
if(user.userName === userId){
this.userTemp.push(user);
}}});
return this.userTemp;
}
users => {
下的表示当我将鼠标悬停在(Users: Users[]) => void is not assignable) => boolean.
我知道我遗漏了一个小细节,但我不知道它在哪里。任何建议将不胜感激。
------------------------------ update 1 --------------- ----------- 现在尝试这个,但它编译但不起作用。
this._searchService.getUserById()
._do(users => {
for(let user of this.users){
if(user.id == userId){
this.userTemp.push(user);
}
}
});
---------------------更新2 ------------------------ - 我从下面的帖子中得到了一些建议,现在我正在尝试这样做,但它没有渲染任何错误。
在组件中:
@Input() users: IUser[] = [];
在组件中调用方法:
case 'role':
this.users = this.getUserByRole(this.role);
console.log(this.role);
break;
组件中的方法:
getUserByRole(role){
this._searchService.getUsers()
.subscribe(users => {
for(let user of users) {
if(user.role == role){
this.users.push(user);
}}});
return this.users;
}
服务方式:
getUsers(): Observable<IUser[]> {
let users = this.http
.get(this.url)
.map(res => res.json());
return users;
}
在控制台中,它会打印输入框中的任何内容,并确认http呼叫的url
有效。
我正在尝试这样做,所以我需要做的就是将http网址更改为有标题和以后的真实网址而不必更改。
--------------更新3 ----------------------
在HTML中我有:
<td>{{data.role | async}}</td>
组件中的方法:
getUserByRole(role){
return this._searchService.getUsers()
.map(data => {
return data.filter((x:any) => x.role == role)
});
}
字段:
@Input() users: Observable<IUser[]>;
调用方法:
case 'role':
console.log(this.getUserByRole(this.role));
this.users = this.getUserByRole(this.role);
console.log(this.users);
break;
错误:
Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
在我的searchService中,我现在正在考虑这样做,但仍然无法正常工作:
findUserByRole(user: IUser) {
return this.http.get(this.url)
.map(res => res.json())
.subscribe(
data => {
}
);
}
答案 0 :(得分:1)
根据更新进行编辑:
不完全确定,您尝试使用<td>{{data.role | async}}</td>
实现的目标,但是如果您想使用异步管道根据特定角色过滤用户,则将users
声明为类似于您的Observable有。当你想要过滤时,请使用你的switch语句(就像你一样):
case 'role':
this.users = this.getUserByRole(this.role);
break;
并在此方法中返回已过滤数组的可观察值
getUserByRole(role){
return this._searchService.getUsers()
.map(data => {
return data.filter((x:any) => x.role == role)
});
}
然后您可以与异步管道一起使用,该管道显示具有来自switch-case的过滤值的用户,无论该过滤器值是什么。在这种情况下,我们根据角色值对上面进行了过滤。
<div *ngFor="let user of users | async">
更新2:
现在看到你的JSON,问题应该是你的数组在一个名为data
的对象中。您需要响应中的数组,因此您需要从对象中提取该数组,因此请稍微更改映射:
return this.http.get(url)
.map((res:Response) =><User[]>res.json().data) // here! Extract the array from the object "data"
.do(data => console.log("User Data: "+JSON.stringify(data)))
.catch((error:any) => Observable.throw(error) || "Mock Data Error get by role")
};
原帖:
filter
实际上是为您进行过滤,您不需要迭代响应。不幸的是,除了作为过滤中的可观察对象之外,我没有看到你能够返回userTemp
。您实际上必须订阅它并将过滤器中的值分配给userTemp
,当您在回调之外返回数组时,以下内容将始终返回undefined
:
getUserById(userId){
this._searchService.getUserById()
.map(users => {
......
});
return this.userTemp; // data has not been assigned yet, when you return it.
}
这就是它的工作原理。您需要在回调中操作数据!以下是一些更多信息:How do I return the response from an Observable/http/async call in angular2?
但是回到你的代码,你可以多次映射,所以在这里你可以使用map
和filter
来获取你想要的数据:
getUserById(userId) {
return this.service.getUsers()
.map(data => {
return data.filter((x:any) => x.userName == userId)
});
}
所以这回归到了你需要它的地方。
但是如上所述,AFAIK你不能将userTemp作为普通的JS数组返回。
答案 1 :(得分:0)
.filter
的回调要求您返回boolean
,但您不返回任何内容(又名void
)。您需要返回boolean
或使用其他方法。