【问题标题】:Value passed in component input changing parent在组件输入中传递的值更改父级
【发布时间】:2017-07-12 12:48:08
【问题描述】:

据我了解,组件中的 Input 字段应该是单向的(父到子)。但是,我将一个值传递给Input,然后在组件中对其进行修改,但我注意到它在父组件中也发生了变化。这对我来说很有意义,因为对象是通过引用传递的,但我猜这意味着 Angular 设置的整个“单向绑定”东西只是一个范式,而不是严格的? Angular 在后台没有做任何事情来强制执行单向绑定?

基本上,我在做:

<session-form [values]="session"></session-form>

session-form 组件中,我将 session.start 从 unixtimestamp 更改为 Moment 对象。但是我注意到在父级中,session.start 也是一个 Moment 对象。

是否有使用此类数据的范例?设置后,我是否应该将输入值复制到严格限制在组件范围内的变量?

【问题讨论】:

    标签: angular


    【解决方案1】:

    查看智能/哑(容器/展示)组件架构。

    基本上这个想法是智能组件包含应用程序的状态或与包含状态的服务对话。哑组件只是渲染从@Input 给它的数据。智能组件将状态传递给哑​​组件。

    您使用事件发射器告诉智能组件更新数据,而不是直接更新哑组件中的数据。这样你就有了单向数据流。

    更多信息在这里: http://blog.angular-university.io/angular-2-smart-components-vs-presentation-components-whats-the-difference-when-to-use-each-and-why/

    【讨论】:

    • 感谢您的信息。这是一种有趣的做法,尽管在这种情况下,我更希望将组件完全分开;它基本上是将接收到的数据格式化为它喜欢的格式。我不明白要求父母为其格式化数据有什么意义。
    • 如果只是格式化,您可以使用日期管道:angular.io/api/common/DatePipe。或者构建一个自定义管道来完成这一刻的工作。
    • 现在还是这样,还是不更新其父级的数据?因为它没有为我更新父母,我不知道是我做错了什么还是改变了
    【解决方案2】:

    是的,对象是通过引用传递的。但是,您不应该使用[(ngModel)] 将对象的属性绑定到表单,因为它是双向绑定,并且由于对象是通过引用传递的,因此它也会在父组件中反映对它的更改。您应该创建一个 FormGroup 并使用 FormBuilder.group() 函数将对象值传递给它,因为它是一个方向性的。

    // Inside of your child component
    @Input() myInput: SomeClass;
    
    form: FormGroup
    
    constructor(
        private formBuilder: FormBuilder
    ) { }    
    
    ngOnInit(): void {
        this.form = this.formBuilder.group({
            prop1: [this.myInput.prop1],
            // etc.
        });
    }
    

    【讨论】:

    • 如上所示,我没有使用双向绑定。我正在使用[value] 的一种方式。另外,我在组件中使用了 FormGroup,但我还需要修改数据以在表单外使用。
    • @RhoVisions 我知道您使用[value] 以一种方式传递输入,但正如您所说,它是对一个对象的引用,如果您在孩子内部使用双向绑定绑定它的任何属性组件,它将反映到父组件。 FormGroup 阻止您这样做。如果您需要在表单外的子组件内部进行双向绑定,则需要自己进行。例如,在名为private prop1: string; 的组件中创建一个变量,并在ngOnInit 中将一个对象的值赋给该变量this.prop1 = myObj.prop1,现在您可以将其绑定为2 路
    • @RhoVisions 我假设您现在在子组件内部使用[(ngModel)] 将这些数据绑定到表单之外。 :)
    • 在我的组件中,我正在修改通过 [value] 传入的数据(将时间戳转换为 Moment 对象),我需要在子组件中显示这些数据。尽管这是一种方式,但我看到父组件的值也更改为 Moment 对象,这对于参考 POV 来说是有意义的,但我没有意识到单向绑定会发生这种情况。我绝不会使用两种方式绑定;我正在使用所有动态表单。
    • @RhoVisions 我的意思是,您正在直接更改对象的属性,正如您自己所说,对象是通过引用传递的。您应该首先将对象属性存储到单独的变量中,对其进行修改,然后使用该变量而不是对象属性。
    猜你喜欢
    • 2021-03-21
    • 2017-05-29
    • 2019-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-03
    • 1970-01-01
    相关资源
    最近更新 更多