简而言之,当导航到/jobs/:id 时,我在这里要做的是在子组件中显示作业数组的特定项的一些属性
部件
export class HomeComponent implements OnInit {
public jobs!: JobInterface[]
constructor(
private jobsService: JobsService
) {
}
ngOnInit() {
this.getJobs()
}
getJobs(page = 1, filters = {city: 'Rome, Italy', level: ''}): void {
this.jobsService.getJobs(page, filters)
.subscribe((response) => {
this.jobs = response.results.map(job => ({
id: job.id,
contents: job.contents,
name: job.name,
publication_date: job.publication_date,
locations: job.locations,
levels: job.levels,
company: job.company
})
)
})
}
}
在路由透视图上一切正常,但在子组件中,作业数组显示为未定义,这使我无法找到所需的项目:
子组件
export class JobDetailsComponent implements OnInit {
jobId : any
@Input() jobs! : JobInterface[]
selectedJob : any
constructor(private ActivatedRoute : ActivatedRoute) { }
ngOnInit(): void {
this.jobId = this.ActivatedRoute.snapshot.paramMap.get('id')
console.log(this.jobs)
this.selectedJob = this.jobs.filter(this.jobId)
}
}
Partent组件的HTML
<app-search-bar (OutputFilters)="getFilteredResults($event)" ></app-search-bar>
<app-job-cards [jobs]="jobs"></app-job-cards>
<app-job-details [jobs]="jobs"></app-job-details>
正确的方法是什么?我在这里做错了什么?
因为路由发生了变化,所以job-details
组件中没有jobs
或job
。此外,组件在检索数据之前进行渲染。
当数据准备好时,您可以添加一个标志来渲染组件,然后您可以将job-details
组件移动到job-cards
组件,并通过路由器从那里传递一个job
,如下所示:
- 在数据准备就绪时添加一个标志来渲染组件:
export class HomeComponent implements OnInit {
dataReady:boolean = false;
// add after the response..
this.dataReady = true;
在模板中:
<app-job-cards *ngIf="dataReady" [jobs]="jobs"></app-job-cards>
然后:
- 从
home-component
中删除app-job-details
从job-cards
模板通过router
将job
传递到job-details
组件:
<a mat-stroked-button routerLink="jobs/{{job.id}}" [state]="job">See More</a>
然后在CCD_ 13组件中通过CCD_
ngOnInit(): void {
this.selectedJob = window.history.state;
}
但这是一种糟糕的方法,而且当直接访问时,路由也会是空的。。你应该决定怎么处理它。。
一种更好的方法是将jobs
存储在jobs-service
而不是home-component
中,并通过组件之间共享的父/子级传递它们,并添加getJobs
和getJobDetails
方法来获取或获取作业,或者为job-details
组件查找(而不是过滤(单个作业(如果您希望详细信息页面总是有一些数据,则可能获取单个作业(,这需要进行大量重构。
编辑:共享服务数据:
将处理从家庭组件转移到作业服务。在那里,组合获取和处理方法,如果没有获取作业,则获取作业,否则返回作业,作为Observable。然后,订阅该方法以从每个组件获取作业。
尝试:
- 就业服务
getJobs(): Observable<JobInterface[]> {
if(this.jobs?.length > 0) {
return of(this.jobs);
}
return this.fetchJobs();
}
fetchJobs(page = 1, filters = { city: 'Rome, Italy', level: '' }): Observable<JobInterface[]> {
const params = new HttpParams({ encoder: new CustomHttpParamsEncoder() })
.set('category', 'Science and Engineering')
.set('page', page)
.set('location', filters.city)
.set('level', filters.level)
return this.http.get<APIResponseInterface>(this.url, { params })
.pipe(map(response => {
this.jobs = response.results.map(job => ({
id: job.id,
contents: job.contents,
name: job.name,
publication_date: job.publication_date,
locations: job.locations,
levels: job.levels,
company: job.company
})
)
return this.jobs;
})
);
}
- 主页组件
getJobs(): void {
this.jobsService.getJobs().subscribe((jobs: JobInterface[]) => {
this.jobs = jobs;
this.dataReady = true;
});
}
- 作业详细信息组件
ngOnInit(): void {
this.jobId = this.ActivatedRoute.snapshot.paramMap.get('id')
this.jobsService.getJobs().subscribe((jobs:JobInterface[]) => {
this.selectedJob = jobs.find(job=> job.id == this.jobId);
});
}
filter方法将直接调用jobsService.fetchJobs
,并在整个过程中同时修改作业。
看看这个例子
如何在组件之间共享来自http响应的数据?
也可以在这里查看其他解决方案