简体   繁体   English

如何更新子级中父级的对象数据

[英]How to update object data of parent in child

I am making custom component for dropdown.我正在为下拉列表制作自定义组件。 I have one config object which I am initializing in ngOnInit() , and I am combining the default configs and configs provided by user as an @Input() , But at run time from parent component, If I am making any changes in my config object, it is not updating in ngOnChanges() method of my child.我有一个在ngOnInit()初始化的配置对象,并且我将用户提供的默认配置和配置组合为@Input() ,但是在父组件的运行时,如果我在我的配置中进行任何更改对象,它没有在我孩子的ngOnChanges()方法中更新。

I tried this:我试过这个:

child component子组件

@Input() config: MyConfig;
        @Input() disabled: boolean
        
        ngOnChanges() {
                console.log('config', this.config); // this is not
                console.log('disabled', this.disabled); // this is detecting
            }

parent component html父组件html

<button (click)="changeConfig()">Change Config</button>
<app-child [config]="customConfig" [disabled]="newDisabled"></app-child>

parent component ts父组件 ts

newDisabled = false;
customConfig = {
        value: 'code',
        label: 'name',
        floatLabel: 'Select'
    };

changeConfig() {
    this.customConfig.value = 'name';
    this.newDisabled = true;
}

for disbale variable it is working, but for config it is not, Am I doing something wrong?对于 disbale 变量它正在工作,但对于配置它不是,我做错了什么吗? please help请帮忙

You problem is that you ngOnInit is setting the config variable to a new object.你的问题是你ngOnInit正在将config变量设置为一个新对象。 Since the @Input() is called once, this breaks your reference to the original object, and changes will not be detected.由于@Input()被调用一次,这会破坏您对原始对象的引用,并且不会检测到更改。

You can fix this by using a setter and getter.您可以使用 setter 和 getter 解决此问题。 I have added a stack blitz to demo this bellow.我添加了一个堆栈闪电战来演示这个波纹管。

Blockquote 块引用

parent component父组件

import { ChangeDetectorRef, Component, VERSION } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  newDisabled = false;
  customConfig = {
    value: 'code',
    label: 'name',
    floatLabel: 'Select',
  };

  changeConfig1() {
    this.customConfig.value = 'name1';
    this.newDisabled = true;
    console.log('Change Config 1');
  }

  changeConfig2() {
    this.customConfig.value = 'name2';
    this.newDisabled = true;
    console.log('Change Config 2');
  }
}

child component子组件

import { Component, Input } from '@angular/core';

class MyConfig {}

@Component({
  selector: 'hello',
  template: `<h1> config: {{config | json}}</h1><h1> disabled: {{disabled}}</h1>`,
  styles: [],
})
export class HelloComponent {
  private _defaultConfig = {
    key: 'default',
  };

  @Input() disabled: boolean;

  private _config: MyConfig;
  @Input() config: MyConfig;
  set () {
    if (!this.config) {
      this.config = new MyConfig(); // it is a class
    } else {
      this._config = {
        ...this.config,
        ...this._defaultConfig,
      };
    }
  }
  get () {
    return this._config;
  }

  ngOnChanges() {
    console.log('config', this.config);
    console.log('config', this._config);
    console.log('disabled', this.disabled);
  }
}

Input object are compared by reference, so if you want to reflect changes in your child component and trigger ngOnChanges do this:输入对象通过引用进行比较,因此如果您想反映子组件中的更改并触发ngOnChanges请执行以下操作:

changeConfig() {
 this.customConfig = {...this.customConfig, value: 'name'};;
 this.newDisabled = true;
}

And also move your below code from ngOnInit to ngOnChanges , chances are that at the time of initialisation input chagnes may not be available.并将您的以下代码从ngOnInit移动到ngOnChanges ,可能在初始化时输入更改可能不可用。

if (!this.config) {
   this.config = new MyConfig(); // it is a class
 } else  {
    this.config = {
           ...this._defaultConfig,
           ...this.config
          };
 }

The problem is that the change detection is only triggered if the object customConfig is changed.问题是只有在对象customConfig发生更改时才会触发更改检测。 In you example, only the value property is updated.在您的示例中,仅更新value属性。 What you can do is the following in the parent.component.ts :您可以在parent.component.ts执行以下操作:

 changeConfig() { this.customConfig = Object.assign(this.customConfig, { value: 'name'}); this.newDisabled = true; }

This will create a new config object which contains the updated value property and all the other old properties of the old customConfig .这将创建一个新的配置对象,其中包含更新的value属性和旧customConfig所有其他旧属性。

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

相关问题 如何使用ChangeDetectionStrategy在父子组件之间进行数据更新 - How to use ChangeDetectionStrategy for data update between parent-child components 在子组件中过滤道具后如何更新父数据? - How to update parent data after filter props in child component? 如何使用从React中的子级获取的数据更新父级组件中的状态 - How to update state in parent component with data taken from child in React Javascript-从子回调中更新父对象 - Javascript - update parent object from child callback 如何在 angular 的父组件中显示 object 数据 - How to display object data in child component from parent in angular 如何最好地将 JSON 子数据对象数组重组为父数组 - How best to restructure JSON child data object arrays into parent array 如何将对象数据从父组件传递到子组件? - How to pass object data from parent to child components? 当子 object 变量被修改并且它的父级和嵌套 JSON 中的大多数父级相同时,如何更新父级 object 变量 - how to update parent object variable when child object variable is modified and same for it's parent and till most parent in nested JSON 如何将子对象划分为父对象? - How to scope child to parent object? vuejs 从子组件更新父数据 - vuejs update parent data from child component
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM