[英]Angular @Input getter/setter and non-primitive values
問題:我想每次綁定子組件的對象中的屬性發生變化時都能調用一個函數。 但是,即使可以看到綁定的輸入屬性更新,setter也只被調用一次。
這一切都來自於需要將子組件綁定到其父組件屬性,該屬性恰好是具有深層嵌套屬性的復雜對象。 我已經了解到,當對象中的嵌套屬性發生更改時,Angular onChange事件不會觸發。 因此決定使用getter / setter。 然而,正如這個問題所見,使用getter / setter也無效。 我已經改變了我的子組件以訂閱父組件訂閱的相同Observable,從而直接從服務接收更新並繞過父組件。 我已經對Angulars綁定和TypeScript getter / setter進行了大量研究,並且從各方面來看,它看起來像我的代碼顯示工作,但事實並非如此。
目標:了解為什么使用帶有getter / setter的@Input綁定到子組件中的父組件屬性不能像非主要類型那樣工作。 是否存在我缺少的基本概念或我的代碼中是否存在實現錯誤?
我將在這里展示一些源代碼,並為任何希望看到它實時運行的人附加StackBlitz。 StackBlitz現場演示
@Injectable()
export class MockDataService {
public updateSubject: Subject<any> = new Subject();
public numObj = {
'prop1': 'stuff',
'prop2': 'stuff',
'prop3': 'stuff',
'prop4': 'stuff',
'level1': {
'level2': {
'target': 0 //target is the prop that will be getting updated
}
}
}
constructor() {
this.startDemo();
}
private startDemo(): void {
//This is simulating the server sending updates
//to the numObj
setInterval(() => {
this.numObj.level1.level2.target += 1;
this.update();
}, 4000);
}
private update(): void {
try {
this.updateSubject.next(this.numObj);
} catch (err) {
this.updateSubject.error(err);
}
}
}
app.component.html <child-cmp [targetNumber]="targetNumber"></child-cmp>
export class AppComponent implements OnInit {
public targetNumber: any;
public displayCurrentNumber: number;
constructor(private mockDataService: MockDataService){}
ngOnInit(){
this.mockDataService.updateSubject.subscribe({
next:(data) => this.onUpdate(data),
error: (error) => alert(error),
});
}
private onUpdate(data: any): void{
if(data){
this.targetNumber = data;
this.displayCurrentNumber = data.level1.level2.target;
}
}
}
export class ChildCmpComponent {
private _targetNum: any;
public displayNumberObj: any;
public displayNumber: number;
public changeArray: string[] = [];
@Input()
set targetNumber(target: any){
this.changeArray.push('Setter(),');
this._targetNum = target;
this.setDisplay(this._targetNum);
}
get targetNumber(): any{
this.changeArray.push('Getter(),');
return this._targetNum;
}
private setDisplay(target: any): void{
this.changeArray.push('setDisplay(),');
this.displayNumberObj = target;
this.displayNumber = target.level1.level2.target;
}
}
這有兩個部分:
export interface InputDecorator { /** * Declares a data-bound input property. * * Angular automatically updates data-bound properties during change detection. *
為了幫助解釋這一點,我將使用以下對象ObjA:
public ObjA = {
'prop1': 'value1',
'prop2': 'value2'
}
當數據綁定屬性的值發生更改時,Angulars會更改檢測觸發器 。 但是,當綁定的屬性是ObjA
類的對象時,它是ObjA
的引用,而不是對象本身。 因此,當ObjA
的屬性值發生變化(狀態變化)時,角度變化檢測不會觸發。 角度是不知道的狀態ObjA
,而是參考ObjA
。
感謝@JBNizet和@ Jota.Toledo向我提供的信息(在上面的評論中)我需要理解這個主題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.