在子组件中更改输入参数是否正常,还是应该将所有输入对象都视为只读对象,然后将任何更改发回给父组件并将其委托给父组件?修改输入参数是否会引起任何问题。
class ChildComponent {
@Input() parentParam;
@Output() clickValEvent = new EventEmitter<boolean>();
let parentParamClone = Object.assign({}, parentParam);
childClickEvent(val) {
//Update value locally.
// parentParam.clickVal = val;
//Inform parent & let it do necessary change.
// this.clickValEvent.emit(val);
//Only play with local clone.
// parentParamClone.clickVal = val;
}
}
答案 0 :(得分:0)
以只读方式传递您的@Input
是我最常看到的,
这样,父母的财产就保持不变。
如果@Input
的副本对您有用,则表示您
想要仅在孩子的组件内部以及所有
更改不会影响父级。
在必须更改对象并将其保留在父组件中时使用输出是一种方法(对我来说,这是更好的选择),但是我习惯于使用两种方式绑定而不是使用回调。 / p>
在您的示例中,如果您想要一个@input
属性,以便在子组件中更改其值并改变其父亲属性,则应考虑两种方式绑定BANANA IN A BOX
,因此代码应看起来像像这样:
class ChildComponent {
@Input() parentParam;
@Output() parentParamChange = new EventEmitter<boolean>(); // <- this EventEmitter must have the parentParam type.
let parentParamClone = Object.assign({}, parentParam);
childClickEvent(val) {
//Inform parent & let it do necessary change, when you
// update the parent's value, it will be reflected in this component.
this.parentParamChange.emit(val);
}
您应该在html模板中使用这种方式:
...
[(parentParam)]="propertyYouArePassingHere"
...
代替
...
[parentParam]="propertyYouArePassingHere"
(clickValEvent)="captureOutputCallback()"
...
注意:要使其正常工作,您必须具有遵循以下模式的输出名称:
inputThatYouWantMakeTwoWayBindName
+ Change
,这就是我将输出重命名为parentParamChange
的原因。
答案 1 :(得分:0)
没错,是的,您可以修改子组件中的 @input
值,它会反映在您的父组件中。但是,您应该避免这种情况的原因有两个:
它不适用于原始值,如果您希望更改 @input
原始值并反映在您的父组件中,这将不起作用。
这不是一个好的做法,它为所有子组件提供了任意更新 @input
对象的机会,并使我们难以追踪值的变化。因此,使用 @output
为我们在未来维护代码方面节省了大量精力,因为它更具声明性。
我觉得很奇怪,我无法从 Angular 文档中找到对此的任何官方解释。与 ReactJs
和 VueJs
不同,它们非常不鼓励我们改变子组件中的 props
。