簡體   English   中英

Angular 10 - 修改 model 時視圖不更新

[英]Angular 10 - View doesn't update when model is modified

Angular 10.1.6、TypeScript 4.0.5

你好

語境

在我的 webapp 中,我有 3 個組件。

組件 A存儲一個Array<Image>

export class ComponentParentA implements OnInit {
  images: Array <Image> ;

  addImageToList(newImage: Image) {
    this.images.push(newImage)
  }
}

組件 C顯示圖像列表。

export class ComponentChildC implements OnInit {

  @Input() images: Array <Image>;
}

組件 C 從組件 A html 模板調用,如下所示:

<ComponentChildC [images]="images"></ComponentChildC>

B組負責聯系我的API,加一張之前選好的圖。 API返回一個Image object,對應我的model。 組件發出圖像,因此 ComponentA 將返回的圖像添加到其數組中(調用 addImageToList)
addImage 是 this.http.post ( HttpClient ) 的 Observable 返回

export class ComponentChildB implements OnInit, AfterViewInit {
  @Output() eventCreateImage : EventEmitter<Image>;

  addImage(data) {
    this.service.addImage(data).subscribe((image) => {
        this.eventCreateImage.emit(image)
      })
  }

}

組件 A 像這樣調用組件 B:

<ComponentChildB (eventCreateImage)="addImageToList($event)"></ComponentChildB>

問題

當我單擊按鈕時,組件 B 添加圖像。 此點擊觸發addImage function。 所有組件都正常工作,圖像保存在我的服務器上。 API 返回圖像,后者正確存儲在組件 A 的數組中。但是,組件 C 的視圖沒有更新,新創建的圖像也沒有出現。 如果我再次單擊該按鈕,則會存儲一個新圖像。 這一次,我之前看不到的之前的圖像正確顯示了。 新圖沒有。

我希望圖像直接出現。

我已經做過的

我在 web 上看到了類似的問題。

  • 首先,我嘗試在addImageToList function 中用this.images = this.images.concat(newImage)替換this.images.push(newImage) 它不起作用。
  • 接下來,我看到了,因為 images 是一個數組,所以當我在數組中添加新圖像時,Angular 沒有檢測到任何變化。 我讓我的組件 C 實現了 OnChange 接口。 實際上,不會調用 ngOnChange function。
  • 我在這里看到我可以嘗試手動重新加載我的組件所以我讓我的組件 C 實現 DoCheck。 奇怪的東西出現了。 當我單擊按鈕並在組件 C 的 ngDoCheck 中執行console.log(this.images)時,我看到列表已正確更新。 但是圖像仍然沒有出現。 所以我嘗試調用諸如 markForCheck 和 detectChanges 之類的ChangeDetectorRef方法來通知組件發生了變化,但是沒有成功。

如果您知道我的問題可能來自哪里,如果您能幫助我,我將不勝感激

我沒有測試,但我認為這是導致策略檢測的原因。 您可以嘗試 3 種不同的解決方案(我現在無法測試,但通常它會起作用)。

PS:對不起我的英語

1/ 在您的 object @Component 在您的組件中添加 changeDetection

@Component({
  selector: 'app-component',
  template: `...`,
  changeDetection: ChangeDetectionStrategy.OnPush
})

然后在你的 function addImageToList() 替換你的代碼

addImageToList(newImage) {
   this.images = [...this.images, newImage]
}

2/ 在您的組件 C 中,將您的 @Input 替換為

@Input() set images(value: Array <Image>) {
      myImages = value
 }

html 中的屬性綁定將是 myImages 在此上下文中

3/ 您可以使用服務 ChangeDetectorRef 手動更改策略檢測。 在您的構造函數組件 A 中添加此服務,然后在 function 中添加:

constructor(
     private cd: ChangeDetectorRef
   ){}

  addImageToList(newImage: Image) {
    this.images = [...this.images, newImages];
    this.cd.markForCheck();
  }

如果此解決方案不起作用,請查看 Angular 中的檢測策略文檔或嘗試將 1 和 2 混合在一起

暫無
暫無

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

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