【问题标题】:How can I pass the same data multiple times from parent to component in Angular?如何在 Angular 中多次将相同的数据从父级传递到组件?
【发布时间】:2019-06-06 14:32:58
【问题描述】:

我有两个相互通信的组件,一个常规组件(父)和一个引导模式组件(子)。 父母和孩子都有一个记录表。在父表中,每条记录都有一个复选框。当我选择一个或多个复选框并单击一个按钮时,会触发一个尝试填充子表的事件。

孩子的表被填充,我可以从中删除我希望的记录。如果我删除一些记录,关闭模式(关闭子)并决定再次从父级向子级发送相同的数据,则不会触发Input 事件。但是,如果我选择检查父项中的不同记录并将它们传递给子项,则会正确触发 Input 事件。

这是我所拥有的:

ParentComponent.component.html

<child-component #createNewProductRequestModal [data]="newProductRequest"></m-child-component>

ParentComponent.component.ts

private onNewProductRequest(toSend){
  this.newProductRequest = toSend;
  $('#createNewProductRequestModal').appendTo("body").modal('toggle');
}

ChildComponent.component.ts

@Input('data')
set data(data: any) {
  if (data !== undefined || data !== "") {
    this.products = data;
    console.log("data");
  }
}

constructor() { }

ngOnInit() { }

为了在渲染子表之前测试数据是否更改,我将父级传递的数据记录到控制台。使用此代码,每次我在不更改 toSend 变量的情况下执行父级的 onNewProductRequest(toSend) 时,子级的模态渲染但不执行 Input 事件,因此不会更改数据。

【问题讨论】:

    标签: javascript angular


    【解决方案1】:

    当您第二次向子组件发送相同的数据时,Angular 不会将此注册为对 @Input() 的更改,因为您传递的对象引用与您第一次传递的对象引用相同,而 Angular 是只是比较参考。

    试试这个小改动:

    private onNewProductRequest(toSend){
      this.newProductRequest = { ...toSend };
      $('#createNewProductRequestModal').appendTo("body").modal('toggle');
    }
    

    这意味着您将数据对象的浅表副本传递给子对象,而不仅仅是原始对象的修改版本。由于这个浅拷贝将对原始对象有不同的引用,Angular 会将其作为更改来获取并触发您的 @Input 设置器。

    【讨论】:

      【解决方案2】:

      当您将数据分配给输入时,第一次检测到更改是因为对象发生了更改,但是如果您更改对象内部的属性,则引用和对象仍然相同,因此不会触发更改。解决方案是克隆您通过输入发送给孩子的对象。尝试更改此行:

      this.newProductRequest = toSend;
      

      为此:

      this.newProductRequest = {...toSend};
      

      【讨论】:

        【解决方案3】:

        你可以使用ngOnChanges

        来自angular docs的定义

        一种回调方法,在默认更改检测器检查数据绑定属性后立即调用(如果至少有一个属性发生了更改),并且在检查视图和内容子项之前。

        您在子元素上有一些输入

          @Input() nameOfInput: any;
        

        您的子组件必须像这样实现OnChanges

        export class ChildComponent implements OnChanges {
        
        

        在下一步中,您希望对输入的每一次更改都做一些事情。

         ngOnChanges(changes: SimpleChanges) {
            console.log(changes);
            if ('nameOfInput' in changes) {
                console.log('Old value: ', changes.nameOfInput.previousValue);
                console.log('New value: ', changes.nameOfInput.currentValue);
            }
          }
        

        看看这个例子。

        Example

        【讨论】:

        • 谢谢!它确实让我找到了解决方案,但我仍然不明白 ngOnChanges 是如何工作的......
        【解决方案4】:

        试试

        在子组件中

        import {Component, OnChanges, SimpleChanges, Input} from '@angular/core';
        ngOnChanges(changes: SimpleChanges) {
             for (let propName in changes) {  
            let change = changes[propName];
        let curVal  = JSON.stringify(change.currentValue);
            let prevVal = JSON.stringify(change.previousValue);
        
                console.log(curVal);
                console.log(prevVal);
             }
        }
        

        【讨论】:

        • 我不明白这应该做什么,但没有任何改变。它具有完全相同的行为,只有在传递的数据不同时才会执行。
        • 我更新了一些东西,并能够使用它找到解决方案。谢谢!
        • 如果它解决了您的问题,那么您可以单击它作为有用的答案。
        • 我做了,但其他人否决了它,所以它显示为 0
        猜你喜欢
        • 1970-01-01
        • 2020-04-05
        • 2017-06-25
        • 2017-12-24
        • 2020-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-31
        相关资源
        最近更新 更多