简体   繁体   English

如何在Angular中从父级到组件多次传递相同的数据?

[英]How can I pass the same data multiple times from parent to component in Angular?

I have two components that communicate with each other, a regular component (parent) and a bootstrap modal component (child). 我有两个相互通信的组件,一个常规组件(父)和一个bootstrap模式组件(子)。 Both the parent and the child have a table with records. 父项和子项都有一个包含记录的表。 In the parent's table each record has a checkbox. 在父表中,每个记录都有一个复选框。 When I select one checkbox or more and click on a button, an event is triggered that tries to populate the child's table. 当我选中一个或多个复选框并单击某个按钮时,会触发一个尝试填充子表的事件。

The child's table gets populated and I have the ability to delete the records I wish from it. 孩子的表被填充,我有能力删除我想要的记录。 If I delete some records, close the modal (close the child) and decide to send the same data from the parent to the child again, the Input event is not triggered. 如果我删除了一些记录,关闭模态(关闭子项)并决定再次从父项向子项发送相同的数据,则不会触发Input事件。 However, if I choose to check different records in the parent and pass them to the child, the Input event is triggered correctly. 但是,如果我选择检查父级中的不同记录并将其传递给子级,则会正确触发Input事件。

Here's what I have: 这就是我所拥有的:

ParentComponent.component.html ParentComponent.component.html

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

ParentComponent.component.ts ParentComponent.component.ts

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

ChildComponent.component.ts ChildComponent.component.ts

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

constructor() { }

ngOnInit() { }

To test if the data is changed before I render the child's table, I log the data passed by the parent to the console. 要在呈现子表之前测试数据是否已更改,我将父项传递的数据记录到控制台。 With this code, every time I execute the parent's onNewProductRequest(toSend) without changing the toSend variable, the child's modal renders but doesn't execute the Input event therefore not changing the data. 使用此代码,每次执行父项的onNewProductRequest(toSend)而不更改toSend变量时,子项的模态呈现但不执行Input事件,因此不更改数据。

You can use ngOnChanges 您可以使用ngOnChanges

Definition from angular docs 角度文档的定义

A callback method that is invoked immediately after the default change detector has checked data-bound properties if at least one has changed, and before the view and content children are checked. 在默认更改检测器检查数据绑定属性后立即调用的回调方法(如果至少有一个已更改),并且在检查视图和内容子项之前。

You have some Input on child element 你有一些关于子元素的输入

  @Input() nameOfInput: any;

Your child component must implement OnChanges like this: 您的子组件必须实现OnChanges如下所示:

export class ChildComponent implements OnChanges {

And in next step you want do something on every change of inputs. 在下一步中,您希望在每次输入变化时都做一些事情。

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

Look at this example. 看看这个例子。

Example

When you assign the data to the input, the first time detect the changes because the object changes, but then if yo change properties inside the object the reference and the object still be the same, so the changes doesn't fire. 当您将数据分配给输入时,第一次检测到更改,因为对象更改,但是如果您更改对象内的属性,则引用和对象仍然相同,因此更改不会触发。 The solution is clone the object that you're sending via input to the child. 解决方案是克隆您通过输入发送给孩子的对象。 Try changing this line: 尝试更改此行:

this.newProductRequest = toSend;

For this: 为了这:

this.newProductRequest = {...toSend};

When you send the same data to the child component a second time, Angular does not register this as a change to the @Input(), as you are passing the same Object reference that you passed the first time, and Angular is just comparing the references. 当您第二次将相同的数据发送到子组件时,Angular不会将其注册为对@Input()的更改,因为您传递的是第一次传递的相同Object引用,而Angular只是比较引用。

Try this small change: 尝试这个小改动:

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

This will mean that you pass a shallow copy of the data Object to the child, rather than just a modified version of the original Object. 这意味着您将数据对象的浅表副本传递给子对象,而不仅仅是原始对象的修改版本。 As this shallow copy will have a different reference to the original Object, Angular will pick it up as a change and trigger your @Input setter. 由于这个浅拷贝将具有与原始对象不同的引用,因此Angular会将其作为更改进行拾取并触发您的@Input设置器。

try 尝试

in child component 在儿童组件中

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);
     }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 React 多次将数据从同一个子组件传递给父组件 - React pass data from same child to parent component multiple times 如何以角度将多个数据从子组件传递回父组件? - How to pass multiple data back from child to parent component in angular? 如何将数据从子组件传递到父组件 Angular - How to Pass data from child to parent component Angular 如何在 Vue.js 中将数据从父组件传递到子组件? - How can i pass data from parent component to a child component in Vue.js? 如何在 Angular 中将组件从父组件复制并传递给子组件? - how can i copy and pass components from a parent to a child component in Angular? ReactJS - 如何在同一事件中将数据从子组件传递到父组件和父组件到子组件? - ReactJS - How to pass data from child to parent component & parent to child component on the same event? 如何在React中将多个数据作为对象从子组件发送到父组件? - How can i send multiple data as an object to parent component from child component in React? 来自父级的 Angular 子组件事件多次触发 - Angular child component event from parent fires multiple times 如何将状态从这个子组件传递给父组件? - How can I pass the state from this child to parent component? 如何将从 http 获取的数据从 Mat-Dialog 组件传递到 Angular 6 中的父组件? - How to pass data fetched from http, from a Mat-Dialog Component to a Parent component in angular 6?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM