[英]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.