我的教育经历如下:
<cdk-virtual-scroll-viewport itemSize="5" class="list-scroll">
<app-education-item *ngFor="let education of loadedEducations"
(isSelected)="changeSelected(education)"
[ngClass]="{ selected: education == loadedEducation }"
[education]="education"
(isRemoved)="removeEducation(education)"
></app-education-item>
</cdk-virtual-scroll-viewport>
并且是以下组件
<div [ngClass]="{ 'list-item-container-collapsed' : isCollapsed, 'list-item-container': !isCollapsed, 'unselected': !isActive, 'selected': isActive}" (click)="selectEducation()">
<div class="top-items-container" style="display: flex;">
<div class="item-text">
<span class="txt-header">{{educationHeader}}</span>
<p class="txt-date">
<span>{{startDate}}</span> -
<span>{{endDate}}</span>
</p>
</div>
</div>
具有以下逻辑,用于显示从参数中获取的数据:
export class EducationItemComponent implements OnInit {
@Input()
education: Education;
isCollapsed = false;
isActive = false;
startDate: string;
endDate: string;
educationHeader: string;
educationDescription: string;
constructor() { }
ngOnInit(): void {
console.log(this.education);
this.startDate = this.education.startDate != '' ? formatDate(this.education.startDate, 'MMM yyyy', 'en-US')
: formatDate(new Date(), 'MM YYYY', 'en-US') ;
this.endDate = this.education.endDate != 'present' ? this.endDate = formatDate(this.education.endDate, 'MMM yyyy', 'en-US')
: this.education.endDate;
this.educationHeader = this.education.degree == undefined || this.education.description == undefined ? ''
: this.education.degree + ' at ' + this.education.school;
if (!this.education.description.enUS && this.education.description.nlNL) {
this.educationDescription = this.education.description.nlNL;
} else if (this.education.description.enUS) {
this.educationDescription = this.education.description.enUS;
}
}
我使用自定义事件来处理更新
@Output() updatedValue: EventEmitter<any> = new EventEmitter<string>();
constructor() {}
ngOnInit(): void {}
fieldChanged(changes: SimpleChanges) {
this.updatedValue.emit(changes);
}
然后我有以下 html 用于操作数据:
<div class="update-wrap">
<div class="list-header">Update education</div>
<div>
<div class="col-sm-6 input-wrapper">
<app-input-field
label="Institution"
[value]="loadedEducation.school"
(updatedValue)="loadedEducation.school = $event"
></app-input-field>
</div>
<div class="col-sm-6 input-wrapper date-picker-input">
<app-input-field
label="Degree"
[value]="loadedEducation.degree"
(updatedValue)="loadedEducation.degree = $event"
></app-input-field>
</div>
</div>
</div>
但是,字段 [value]="loadedEducation.school" (updatedValue)="loadedEducation.school = $event" 中的更新数据不会与子组件绑定,因此在刷新并获取之前不会显示任何内容来自数据库的数据。
我可以尝试实现哪些可能性?
我尝试实现 ngOnChanges,但没有成功。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
当您更改列表中项目的属性时,loadedEducations 列表不会更改。尝试刷新列表(
this.loadedEducations = returnedEducations)或在项目中使用状态管理问题的根本原因是
@Input()无法检测到对象和数组内部的更改,因为它们都是 引用类型。您的education属性是一个对象,因此在父组件中进行的直接改变属性的更改(例如education.school = 'newValue')不会触发子组件的属性@Input() education的任何更改有几种方法可以解决这个问题,每种方法都有其优点和缺点:
仅传递您需要的属性作为基元
parent.component.tsparent.component.htmlchild.component.tsexport class EducationItemComponent implements OnChanges { @Input() school: string; @Input() degree: string; ngOnChanges(changes: SimpleChanges): void { // will emit whenever .school or .degree is changed in the parent } }优点:
缺点:
@Input数量的增长,变得笨重Education接口)绑定更改时在父级中重建对象
parent.component.ts深度克隆
parent.component.htmlchild.component.tsexport class EducationItemComponent implements OnChanges { @Input() education: Education; ngOnChanges(changes: SimpleChanges): void { // will emit whenever updateEducation() is called in the parent } }优点:
Education接口,保持父组件和子组件之间的语义耦合缺点:
updateEducation()函数将反应性元素传递到您的子组件中,例如
BehaviorSubject,并直接订阅更改parent.component.tsparent.component.htmlchild.component.tsexport class EducationItemComponent implements OnChanges { @Input() educationSubject: BehaviorSubject;
} child.component.html优点:
educationSubject放入服务中,并将相同的服务注入到任何需要它的组件中缺点:
updateEducation()函数| async)等