簡體   English   中英

如何按值將對象傳遞給 Angular2+ 組件

[英]How to pass object by value into Angular2+ component

假設我有一個組件,它接受一個Foo實例並顯示一個表單來編輯它。

export class ChildComponent implements OnInit {
  @Input() foo : Foo;
  @Output() onChange : EventEmitter<Foo> = new EvenEmitter<Foo>();

  constructor() {
  }

  ngOnInit() {
  }
}

我將該ChildComponent嵌套在ParentComponent

<div id="parent">
  <app-child-component [foo]="parentFoo"></app-child-component>
</div>

現在,即使我在這里使用了單向綁定,由於foo是一個對象,因此通過引用傳遞,在ChildComponent中對它所做的任何更改也會反映在ParentComponent

我怎樣才能防止這種情況? 有沒有辦法按值傳遞? 任何最佳實踐?

好的,到目前為止我最好的解決方案是這樣的:

export class ChildComponent implements OnInit {
  private _foo : Foo;
  @Input()
  set foo(value : Foo) { this._foo = Object.create(value || null); }
  get foo() : Foo { return this._foo; }

  @Output() onChange : EventEmitter<Foo> = new EventEmitter<Foo>();

  constructor() {
  }

  ngOnInit() {
  }
}

這似乎確實有效,但是單個屬性需要大量代碼。 我仍然不明白為什么 Angular 中沒有內置這樣的功能(例如@InputByValue裝飾器)。

我認為當我希望更改從孩子反映到父母時,我會使用雙向綁定[(foo)]="foo" 我在這里錯過了什么嗎? 有什么理由不做我想做的事嗎?

正如 Gunter 在這個答案中所說: Angular2:通過引用傳遞組件之間的交互

原始值(字符串、數字、布爾值、對象引用)按值傳遞(復制),對象和數組按引用傳遞(兩個組件都獲得對同一對象實例的引用)。

這與 Angular 無關,它只是 Javascript 和 Typescript 的工作方式。

事實上,我會說,如果你將一個對象傳遞給一個子組件並試圖在那里改變它,你正在更新同一個對象,所以它的值保持同步是一種“很好”的方式。

但是,如果要分叉該值,則需要以一種或另一種方式創建本地副本。 正如評論中提到的,您可以通過在子組件中對對象進行深層復制然后更改該值來實現。 這是一個說明此方法的小 Stackblitz 示例: https ://stackblitz.com/edit/angular-axr5zf。

您可以嘗試 const copy = { ...original } 創建對象的副本

您需要生成一個新對象,而不是直接使用輸入引用。 一個快速的解決方案是使用Spread 語法生成對象的新副本並在模板中使用它。

@Input('foo') fooRef : Foo;
foo: Foo;
.
.
.
ngOnInit() {
    // creating a new object using the spread syntax
    this.foo = {...this.fooRef};
}

暫無
暫無

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

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