Pengalaman pendidikan saya adalah seperti berikut:
<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>
dan merupakan komponen berikut
<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>
Mempunyai logik berikut untuk memaparkan data yang diperoleh daripada parameter:
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; } }
Saya menggunakan acara tersuai untuk mengendalikan kemas kini
@Output() updatedValue: EventEmitter<any> = new EventEmitter<string>(); constructor() {} ngOnInit(): void {} fieldChanged(changes: SimpleChanges) { this.updatedValue.emit(changes); }
Kemudian saya mempunyai html berikut untuk memanipulasi data:
<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>
Walau bagaimanapun, data yang dikemas kini dalam medan [value]="loadedEducation.school" (updatedValue)="loadedEducation.school = $event"
tidak akan terikat pada komponen anak, jadi tiada apa yang akan dipaparkan sehingga ia menyegarkan dan mendapat data daripada pangkalan data.
Apakah kemungkinan yang boleh saya cuba laksanakan?
Saya cuba melaksanakan ngOnChange tetapi tidak berjaya.
Senarai Pendidikan yang dimuatkan tidak berubah apabila anda menukar sifat item dalam senarai. Cuba muat semula senarai (
this.loadedEducations = returnedEducations
) atau gunakan pengurusan negeri dalam projek andaPunca masalah adalah sebarang perubahan dalam
@Input()
无法检测到对象和数组内部的更改,因为它们都是 引用类型。您的education
属性是一个对象,因此在父组件中进行的直接改变属性的更改(例如education.school = 'newValue'
)不会触发子组件的属性@Input() education
Terdapat beberapa cara untuk menyelesaikan masalah ini, setiap satu dengan kebaikan dan keburukannya:
Luluskan hanya sifat yang anda perlukan sebagai primitif
parent.component.ts
parent.component.html
child.component.ts
Kelebihan:
Kelemahan:
Boilerplate tambahan diperlukan untuk- menerima perubahan kepada komponen kanak-kanak. Apabila bilangan bertambah, ia menjadi sukar digunakan
Anda kehilangan gandingan semantik antara komponen ibu bapa dan anak, ia sebenarnya terikat dengan antara muka yang dikongsi (iaitu - antara muka)
Tidak berskala dengan baik jika sifat juga merupakan jenis rujukan, dalam hal ini sifat ini juga perlu dibongkar dan diluluskan sebagai primitif-
@Input
Education
Bina semula objek dalam induk apabila ditukar
parent.component.ts
Klon Dalam
parent.component.html
child.component.ts
Kelebihan:
Kekalkan penggunaan- antara muka untuk mengekalkan gandingan semantik antara komponen ibu bapa dan anak
Menggalakkan penggunaan - objek tidak berubahSecara amnya ia merupakan amalan yang baik untuk objek
Tidak memerlukan boilerplate tambahan untuk - menerima perubahan kepada subkomponen.
Education
Kelemahan:
Memerlukan boilerplate tambahan untuk- menghantar perubahan kepada komponen anak, iaitu mencipta fungsi berlebihan
updateEducation()
dalam komponen indukSalurkan elemen reaktif ke dalam komponen anak anda seperti
dan langgan terus perubahan
BehaviorSubject
parent.component.ts
parent.component.html
child.component.ts
child.component.html
Kelebihan:
educationSubject
ke dalam perkhidmatan dan menyuntik perkhidmatan yang sama ke dalam mana-mana komponen yang memerlukannyaKelemahan:
updateEducation()
berlebihan| async
), dsb.