Angular 如何基于用户单击父组件中的对象在共享服务的子组件中显示数据?
首先,我将从概述开始,以便更容易理解我的问题 我有一个Angular 如何基于用户单击父组件中的对象在共享服务的子组件中显示数据?,angular,Angular,首先,我将从概述开始,以便更容易理解我的问题 我有一个projects页面,其中列出了使用Spring-Boot-RESTcontroller和数据库从后端获取的多个project对象。每个项目可以有多个模块对象 这里是Project.ts: import { Module } from './module'; export class Project { projectId: number; name: string; description: string;
projects
页面,其中列出了使用Spring-Boot-RESTcontroller和数据库从后端获取的多个project
对象。每个项目
可以有多个模块
对象
这里是Project.ts:
import { Module } from './module';
export class Project {
projectId: number;
name: string;
description: string;
module: Module[];
}
import { Project } from './project';
import { TestCase } from './test-case';
export class Module {
moduleId: number;
project: Project;
name: string;
createdBy: string;
referenceDocument: string;
testCase: TestCase[];
}
和Module.ts:
import { Module } from './module';
export class Project {
projectId: number;
name: string;
description: string;
module: Module[];
}
import { Project } from './project';
import { TestCase } from './test-case';
export class Module {
moduleId: number;
project: Project;
name: string;
createdBy: string;
referenceDocument: string;
testCase: TestCase[];
}
所以,我希望实体结构是清晰的
现在,用户可以单击“项目”页面上的表行。单击将获取项目
对象并将其发送到另一个组件(搜索模块
组件),该组件用于搜索与单击的项目
相关的模块。用户单击项目后,URL应更改为searchModules
HTML模板,其中将显示与该项目相关的所有模块
以下是组件及其HTML模板:
搜索模块.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { Module } from '../module';
import { Project } from '../project';
import { ProjectService } from '../project.service';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-search-modules',
templateUrl: './search-modules.component.html',
styleUrls: ['./search-modules.component.css']
})
export class SearchModulesComponent implements OnInit {
projectModules: Module[];
errorMessage: any;
public project: Project;
constructor(private projectService: ProjectService, private http: HttpClient) { }
ngOnInit() {
}
receiveAndSetClickedProject(project: Project) {
console.log("In Search Component Module: ", this.project);
this.project = project;
}
findModulesForProject(): void {
console.log("Finding modules for Project: ", this.project, " in SearchModules...")
this.projectService.findModulesByProject(this.project).subscribe(responseData => {
this.projectModules = responseData;
console.log(this.projectModules);
if (this.projectModules.length == 0)
alert("This project doesn't have a module yet.")
}, error =>
{
this.errorMessage = error;
window.alert(this.errorMessage);
})
}
}
<div>
<br />
<div class="card" (click)="findModulesForProject()">
<div class="card-header">
<h4 *ngFor="let module of projectModules"> Modules in Project: {{module.project.name}}</h4>
<div class="col-md-7 float-right"></div>
<a [routerLink]="['/modulesForm']" routerLinkActive="router-link-active" class="btn btn-outline-primary"
style="float: right;"> + New Module</a>
</div>
<div class="card-body">
<table class="table table-bordered table-hover">
<thead class="thead-dark">
<tr>
<th scope="col">Module ID</th>
<th scope="col">Module Name</th>
<th scope="col">Project</th>
<th scope="col">Reference Document</th>
<th scope="col">Created By</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let module of projectModules">
<td>{{module.moduleId}}</td>
<td>{{module.name}}</td>
<td>{{module.project.name}}</td>
<td>{{module.referenceDocument}}</td>
<td>{{module.createdBy}}</td>
</tr>
</tbody>
</table>
</div>
</div>
<br />
<br />
</div>
<app-project (sendProject)="receiveAndSetClickedProject($event)"></app-project>
搜索模块.component.html
<div>
<br />
<div class="card" (click)="findModulesForProject()">
<div class="card-header">
<h4 *ngFor="let module of projectModules"> Modules in Project: {{module.project.name}}</h4>
<div class="col-md-7 float-right"></div>
<a [routerLink]="['/modulesForm']" routerLinkActive="router-link-active" class="btn btn-outline-primary"
style="float: right;"> + New Module</a>
</div>
<div class="card-body">
<table class="table table-bordered table-hover">
<thead class="thead-dark">
<tr>
<th scope="col">Module ID</th>
<th scope="col">Module Name</th>
<th scope="col">Project</th>
<th scope="col">Reference Document</th>
<th scope="col">Created By</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let module of projectModules">
<td>{{module.moduleId}}</td>
<td>{{module.name}}</td>
<td>{{module.project.name}}</td>
<td>{{module.referenceDocument}}</td>
<td>{{module.createdBy}}</td>
</tr>
</tbody>
</table>
</div>
</div>
<br />
<br />
</div>
<app-project (sendProject)="receiveAndSetClickedProject($event)"></app-project>
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { Project } from '../project';
import { Router } from '@angular/router';
import { ProjectService } from '../project.service';
import { HttpClient } from '@angular/common/http';
import { Module } from '../module';
@Component({
selector: 'app-project',
templateUrl: './project.component.html',
styleUrls: ['./project.component.css']
})
export class ProjectComponent implements OnInit {
project: Project = new Project();
listOfAllProjects: Project[];
listOfModulesByProject: Module[];
errorMessage: any;
constructor(private router: Router, private projectService: ProjectService, private http: HttpClient) { }
ngOnInit() {
this.projectService.findAllProjects().subscribe(responseData =>
{
this.listOfAllProjects = responseData;
}, error =>
{
this.errorMessage = error;
window.alert(this.errorMessage);
})
}
updateProject(): void {
// this should call ProjectFormUpdateComponent's actual updateProject() method
}
deleteProject(project:Project): void {
// Shouldn't use this.project here. In that case it will refer to the null object created in this file.
// Without this, it refers to the object received from the HTML element.
this.projectService.deleteProject(project).subscribe(responseData => {
alert("Project ID: " + project.projectId + " has been deleted successfully.");
})
}
@Output()
sendProject:EventEmitter<Project> = new EventEmitter<Project>(); // creates the emitter to emit the clicked project.
onSelectProject(project: Project){
console.log("In Project Component: ", project);
this.sendProject.emit(project); // emits the project to the search-modules component
this.router.navigate(['/moduleSearch']); //redirects url to search-modules component
}
}
项目中的模块:{{module.Project.name}
。它有点粗糙,因为我以前从未玩过
我已经尽可能清楚地说明了我的问题,但如果仍然不清楚,请要求进一步澄清
非常感谢您阅读这个大问题。:) 我试着给你举个StackBlitz的例子。希望这能澄清一点问题。它仍然非常简单:)
此外,我在这里添加了我的解决方案的主要部分,作为注释中建议的代码片段
使用附加参数为searchModule组件添加特定路由
在projectList组件中,向每个项目条目添加routerLink,并将实际的projectId传递给路由器
当然,几分钟后就可以在StackBlitz上发布了……为什么你的重定向函数this.router.navigate(['/moduleSearch'])代码>导航到moduleSearch时,可以将projectId作为参数传递。然后在模块搜索中,您可以从后端获取模块。如果我不使用this.router.navigate(['/moduleSearch']),这里就没有多余的emit了。@BhargavChudasama代码>,数据不会传递到其他组件。如果您像这样导航:this.router.navigate(['/moduleSearch'],{queryParams:{projectId:project.Id})
然后在搜索模块中
组件将projectId
作为查询参数。使用它来获取项目和项目模块。感谢StackBlitz。我想,多亏了你和其他人的帮助,我也许能够启动并运行我的项目。我会随时通知你的。请在你的答案中注明相关代码。您应该使用StackBlitz作为参考,而不是答案。@IftifarTaz只是在这里提供我的意见,但是,我认为完整的StackBlitz有助于像我这样的noobs更好地理解上下文和实现潜在解决方案的正确步骤。@IftifarTaz感谢您的建议。我用一些代码片段更改了答案。非常感谢您的帮助。我已经成功地解决了我的问题。事情完成得如此简单,但我们却采取了更复杂的方法,这真是不可思议。
constructor( private route: ActivatedRoute ) {
this.id = parseInt(this.route.snapshot.paramMap.get('projectId'));
}