在嵌套组件中,注入的服务为null。如何在嵌套组件中使用服务
export class ActivityComponent implements OnInit {
constructor(
.
.
public accountService: AccountService //it is null when use in view!!!!
) { }
....
}
<app-some-component>
...
<div *ngFor="let task of tasksService.bindingSource.dataSource">
<app-activity [task]="task"></app-activity>
</div>
...
</app-some-compnent>
<div>{{accountService.getUser(task.userId).name}}</div> <!-- <= error line -->
错误:_co.accountService.getUser(...)未定义
答案 0 :(得分:0)
确保AccountService
在您正在使用的模块的providers
数组中或在应用程序的app.module
中。在最新情况下,您也可以这样做
@Injectable({
providedIn: 'root'
})
export class AccountService {....}
这将自动将服务插入app.module
中,因此您无需手动将其添加到提供程序中。
答案 1 :(得分:0)
恩,如果您有专门的服务,您会喜欢
getUser(user)
{
return this.HttpClient.get('....'+user)
}
返回一个可观察的
如果有喜欢的人
**example of WRONG service
user:any
getUser(user)
{
this.HttpClient.get('....'+user).subscribe(res=>{
this.user=res
}
return this.user //<---here user is null because we are making
//async call
}
好吧,您知道为什么getUser在最后一种情况下返回null,并且在第一种情况下您不能使用accountService.getUser()。value。 accontService
不为null,但accountService.getUser()返回null 。
让我解释一下如何解决有关您需要获取accountService数据的问题。
您可以采取两种方法,获取用户列表,然后获取任务列表,并使用用户的值映射las列表。我们需要使用switchMap和map'rxjs'运算符
想象一下你有
getUserList(): Observable<User[]> {
return this.httpClient.get<User[]>("..."); //get an array of Users
}
getTaskList(): Observable<Task[]> {
return this.httpClient.get<Task[]>("..."); //get an array of Tasks
}
您可以创建一个新方法,该方法返回带有用户名的任务列表
getTaskExtenderList(): Observable<any[]> {
return this.getUserList().pipe(
switchMap((users: any[]) => {
//in users we has the list of users, but we want
//return the task
return this.getTaskList().pipe(
map((task: any[]) => {
//here we has the list of task
task.forEach(x => {
const user = users.find(u => u.userId == x.userId);
x.userName = user ? user.userName : null;
});
return task;
})
);
})
);
}
另一个方法是为每个任务创建一个对用户的调用,并将名称加入任务(此方法是当用户列表很大且每个用户都有一个或两个任务时)
//we has a function
getUser(userId): Observable<User> {
return this.httpClient.get<User>("....."+userId)
}
getTaskExtenderList2(): Observable<any[]> {
return this.getTaskList().pipe(
map((tasks: Task[]) => {
const users = tasks.map((t: Task) => t.userId);
const obs = users
.filter((x, index) => users.indexOf(x) == index)
.map(u => this.getUser(u));
return { uniqueUsers: obs, tasks: tasks };
}),
switchMap((data: { uniqueUsers: Observable<User>[]; tasks: any[] }) => {
return forkJoin(data.uniqueUsers).pipe(
map((users: any[]) => {
data.tasks.forEach(t => {
const user = users.find(u => u.userId == t.userId);
t.userName = user ? user.userName : null;
});
return data.tasks;
})
);
})
);
}
好吧,您在stackblitz中有两个建议
注意:在stackblitz中,我使用“ of”模拟httpClient.get
注2:记住,作为一种好习惯:“服务返回Observable,组件隶属于服务”