簡體   English   中英

Angular @Input() 值相同時不改變

[英]Angular @Input() value is not changed when the value is same

當我運行這個程序時,最初我得到 output 為false , 5 , 500因為我已經在子組件中初始化了它們,但是當我嘗試點擊更新按鈕時,我無法恢復到以前的值。 我期待 output 是true , 10 , 1000 ,但我認為它是false , 5 , 1000 只有不同的數字被改變了。

我該如何解決這個問題,以便我可以獲取我在父組件中設置的值?

鏈接到stackblitz

應用組件.html

<span (click)="clickme()">Update data</span>

應用組件.ts

export class AppComponent  {
  public parentBool: boolean;
  public parentNum: number;
  public p2: number;


  public ngOnInit(): void {
    this.parentBool = true;
    this.parentNum = 10;
    this.p2 = 100;
  }

  public clickme(): void {
    this.parentBool = true;
    this.parentNum = 10;
    this.p2 = 1000;
  }
}

你好.component.ts

@Component({
  selector: 'hello-comp',
  template: `
    <div>
     Boolean value is - {{boolChild}} <br/>
     Number value is - {{numChild}} <br />
     Second number is - {{numChild2}}
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class MyComponent {
  @Input() boolChild: boolean;
  @Input() numChild: number;
  @Input() numChild2: number;


  public ngOnInit(): void {
    this.boolChild = false;
    this.numChild = 5;
    this.numChild2 = 500;
  }
  constructor(private _cd: ChangeDetectorRef){}

    public ngOnChanges(changes: {}): void {
      // this._cd.detectChanges();
      console.log(changes);
    }
}

輸入綁定發生在 ngOnInit 之前,您正在覆蓋 ngOnInit 中的值。

將您的默認值放入聲明中:

@Input() numChild: number = 5;

像那樣

這就是此時子組件中的輸入變量的初始化方式。

  1. 初始化AppComponent ,觸發ngOnInit並渲染模板。
  2. 初始化MyComponent ,觸發ngOnChanges 這將在控制台日志中顯示如下
{
  "boolChild": {
    "currentValue": true,
    "firstChange": true
  },
  "numChild": {
    "currentValue": 10,
    "firstChange": true
  },
  "numChild2": {
    "currentValue": 100,
    "firstChange": true
  }
}
  1. MyComponent中觸發ngOnInit (注意:這是在ngOnChanges之后觸發的)分配值false5500 這就是為什么這些值顯示在模板中而不是最初從AppComponent發送的值的原因。

  2. 單擊AppComponent中的Update data按鈕,它將推送值true101000 它將顯示以下 output

{
  "numChild2": {
    "previousValue": 100,
    "currentValue": 1000,
    "firstChange": false
  }
}

解釋

根據MyComponent中的ngOnChanges ,之前的值為true10100 (來自ngOnInitAppComponent )。 ngOnChanges未注冊值false5500 ,因為它們不是通過Input()更改的。 因此changes顯示了唯一的 object 已從以前的 state 更改,即numChild2 其他 2 個值保持不變,它們不會反映在ngOnChanges中。

一種解決方案是避免在子級的ngOnInit()掛鈎中分配值並在定義期間分配值。

_boolChild: boolean = false;
_numChild: number = 5;
_numChild2: number = 500;

即使進行了這些更改,當您單擊按鈕時,您仍然會在changes變量中僅觀察到numChild2 object,因為這就是SimpleChanges的工作方式。 它只會顯示從之前的 state 更改的值,它不會反映保持不變的值。


這是鈎子調用順序供參考

  • OnChanges
  • 初始化
  • 做檢查
  • 內容初始化后
  • 內容檢查后
  • AfterViewInit
  • AfterViewChecked
  • 銷毀

您是否嘗試過先調用detectChanges?

  ngOnInit() {
    this._cd.detectChanges();
    ....rest of your code...
  }

順便說一句,我不明白你為什么在 ngOnInit() 中設置與第 14 和 15 行相同的值。實際上你不需要......

那么你的問題是當一切都被初始化

父值為,子值為

您正在單擊父跨度。 這會將 parentBool 值設置為True 對於父組件,這不是變化。 因此更改檢測不會觸發。

我從 https://stackblitz.com/edit/angular-jv3sjz 下面的鏈接中分叉了這個https ://stackblitz.com/edit/angular-rgdgd6

您可以嘗試 2 種不同的方法

  1. 捕獲 ViewChildren 並在 Parent https://stackblitz.com/edit/angular-4fqlqg中更新
  2. 有一個服務來維護中間 state,孩子們會聽那個 state。 (如果需要使用ngrx,否則一個簡單的服務就足夠了) (更喜歡這個更好一點,因為它更具可擴展性)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM