繁体   English   中英

如何让子组件检测来自父组件的对象 (@Input()) 在 Angular 中已更改

[英]How to make child component detects object (@Input()) from parent component has changed in Angular

我有一个来自父组件的对象,也收到了与此类似的子组件:

{
  attribute: 'aaaa',
  attribute2: [
    {
      value
    },
    {
      value
    },
    {
      value
    },
  ]
}

此对象是来自父组件的@Input 当我对attribute2数组中的对象进行更改时,我希望子组件检测到所做的更改然后进行更新。 由于这是一个对象,我无法让它工作,所以我在父组件中克隆了整个对象( this.objet = _.cloneDeep(this.object ),然后子组件检测到发生了变化。

有没有其他方法可以不克隆整个对象? 提前致谢

编辑:

子组件

export class ChildComponent implements OnInit, OnChanges {
  @Input() public object: any;
}

html

<div>
   <span>{{object.attribute}}</span>
   <div *ngFor="let items of object.attribute2">{{item.value}}</div>
</div>

父组件

export class ParentComponent implements OnInit {
  public object: any;

  updateObject() {
      this.object.attribute2[1] = 'Changed value';
      this.object = _.cloneDeep(this.object);
  }
}

html

<div>
   <child-component [object]="object"></child-component>
</div>

一种有效的方法是使用 EventEmitter 和服务通信来触发子组件中的更改。

@Tony 提到的方法是使用 ngOnChanges()。 这是检测有界属性变化的一个很好的捷径,但是随着你添加越来越多的绑定,从长远来看,使用这个钩子会影响你的应用程序,因为它会在每次任何绑定属性改变时运行,无论你是否想要它调用。

因此,对于基于服务的通信,我创建了一个示例

在这个例子中,我在添加新数据时使用@Input() 将一个数组绑定到子组件,该数组由父级更新,最新的值传递给服务,然后该服务发出此值。 子组件订阅该值并执行相关代码。

服务:

import { Injectable, EventEmitter } from '@angular/core';

@Injectable({
    providedIn: "root"
})
export class DataService {

  dataUpdated:EventEmitter<any> = new EventEmitter();

  constructor() { }

  setLatestData(data) {
    this.dataUpdated.emit(data);
  }

}

子组件 TS

import { Component, OnInit, Input } from '@angular/core';
import { DataService } from '../data-service.service';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {

  @Input() allData: [];
  latestData: any;

  constructor(private dataService: DataService) { }

  ngOnInit() {
    this.dataService.dataUpdated.subscribe((data) => {
      this.latestData = data;
    });
  }

}

子组件 HTML

<p>
Latest Data: {{ latestData }}
</p>
<h3>List:</h3>
<li *ngFor="let data of allData">
  {{ data }}
</li>

父组件 TS

import { Component } from '@angular/core';
import { DataService } from './data-service.service'

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';
  dataArr = [];

  constructor(private dataService: DataService){}

  onAddTimestamp() {
    let timestamp = new Date();
    this.dataArr.push(timestamp);
    this.dataService.setLatestData(timestamp);
  }

}

父组件 HTML

<hello name="{{ name }}"></hello>
<p>
  Start editing to see some magic happen :)
</p>
<button
(click)="onAddTimestamp()"
>
  Add Timestamp
</button>
<app-child
[allData] = "dataArr"
></app-child>

在您的组件中使用 ngOnChanges() 生命周期方法。

ngOnChanges 在数据绑定属性被检查之后和视图和内容子项被检查之前被调用,如果其中至少一个发生了变化。

有些像这样

@Input() object: string;

ngOnChanges(changes: SimpleChanges) {
    console.log(changes.object.currentValue);
    // You can also use object.previousValue and 
    // object.firstChange for comparing old and new values
}

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM