使用参数化管线Angular时,在子零部件中显示为未定义的阵列



简而言之,当导航到/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组件中没有jobsjob。此外,组件在检索数据之前进行渲染。

当数据准备好时,您可以添加一个标志来渲染组件,然后您可以将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模板通过routerjob传递到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中,并通过组件之间共享的父/子级传递它们,并添加getJobsgetJobDetails方法来获取或获取作业,或者为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响应的数据?

也可以在这里查看其他解决方案

最新更新