如何通过值将对象传递给Angular2 +组件

时间:2018-02-01 14:57:11

标签: javascript angular typescript parameter-passing pass-by-value

我们假设我有一个接收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中。

我该怎样防止这种情况?有没有办法通过价值?任何最佳做法?

4 个答案:

答案 0 :(得分:2)

好吧,到目前为止我的最佳解决方案是这样的:

@InputByValue

这似乎有效,但是它为单个属性提供了大量代码。我仍然不明白为什么Angular中没有这样的功能(例如[(foo)]="foo"装饰器)。

我认为当我希望将更改从子节点反映回父节点时,我会使用双向绑定name。我在这里错过了什么吗?有什么理由不去做我想做的事吗?

答案 1 :(得分:1)

Gunter在这个答案中说:Angular2: Pass by reference to interact between components

  

原始值(字符串,数字,布尔值,对象引用)按值传递(复制),对象和数组通过引用传递(两个组件都获得对同一对象实例的引用)。

这与Angular无关,它只是Javascript的方式,因而也就是Typescript的工作方式。

事实上,我会说,如果你将一个对象传递给一个子组件并尝试在那里进行更改,那么你需要更新同一个对象,所以它的排序是&# 34,漂亮&#34;以某种方式使价值保持同步。

但是,如果要分叉值,则需要以这种或那种方式创建本地副本。如评论中所述,您可以通过在子组件中执行对象的深层复制然后更改该值来实现。这是一个小Stackblitz示例,说明了这种方法:https://stackblitz.com/edit/angular-axr5zf

答案 2 :(得分:0)

您可以尝试 const copy = {...原始} 用于创建对象的副本

答案 3 :(得分:0)

您需要生成一个新对象,而不是直接使用输入引用。一种快速的解决方案是使用Spread syntax生成对象的新副本并在模板中使用它。

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