如何防止子项中的数据更改影响其父项?角度5

时间:2018-10-01 23:07:57

标签: angular typescript

因此,我有一个Angular应用程序,其中使用了多个子组件来为父页面“站点”构建d3图形。

我向父组件上的服务发出请求,该组件将返回站点对象列表,其中包含要绘制的所有数据。我将该数据传递给d3图形组件。

我的问题是:当我在子组件中重组数据时,为什么它似乎会覆盖数据/包括来自原始请求的这些更改(当我在父项上使用console.log时)?我没有使用任何@Output装饰器。

我需要父级中的数据受其子级影响...我不确定为什么会这样!如果可以的话,请提供帮助,如果我可以澄清任何事情,请告诉我。谢谢!

这是我的文件的样子:

sites.component.ts: 我向该服务发出请求,要求我退回所有站点的列表以及它们随附的随机数据。我将它们存储在“站点”中

import { Component, Inject, OnInit, Input } from '@angular/core';
import { DataService } from '../data.service';
import { Http, Response } from '@angular/http';
import { AuthService } from "../services/auth.service";

@Component({
  selector: 'app-sitelist',
  templateUrl: './sitelist.component.html',
  styleUrls: ['./sitelist.component.css']
})
export class SitelistComponent implements OnInit {
  sites;
  constructor( private _dataService: DataService, private http: Http,  public authService: AuthService ) {
  }
ngOnInit() {
    this.authService.getSites()
    .map((res:Response) => (
       res.json() 
     ))
    .subscribe(data => {
       console.log(data)
       this.sites = data
       console.log(this.sites)
    })
  }
}

sites.component.html 我遍历每个站点以将每个“摘要”组件呈现为表格行,并将“站点”数据传递给每个

<table class="responsive-table striped">
  <tbody>
    <tr *ngFor="let site of sites">
        <app-summary [site]="site"></app-summary>
    </tr>
  </tbody>
</table>

Summary.component.ts 对于每个站点,我都呈现摘要组件,并通过“ @Input()站点”接受一个站点的数据;我对其进行了重组,以便将其发送给子级(d3图形组件)时,这些图形已经可以读取。我将其存储在“ site_info”中

import { Component, OnInit, Input, AfterViewInit } from '@angular/core';
import { DataService } from '../data.service';
import { Http } from '@angular/http';
import * as d3 from 'd3';
import { AuthService } from "../services/auth.service"; 
import { Router, ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-summary',
  templateUrl: './summary.component.html',
  styleUrls: ['./summary.component.css'],

})
export class SummaryComponent implements OnInit, AfterViewInit {
  @Input() site;

constructor(private activatedRoute: ActivatedRoute,private _dataService: DataService, private http: Http, public authService: AuthService, private router:Router ) {}
date: Date;
dates: any;
value: Number;
eachobj: any;
data: any;
average: any;
site_info: any;

ngAfterViewInit(){

}
ngOnInit() {

this.data = this.site
console.log(this.site)

this.dates = Object.keys(this.data.historical_data)
this.site_info = Object.keys(this.data.historical_data).map(key=>this.data.historical_data[key])

this.site_info = this.site_info.map((obj, i) => {
  if (!obj) {
    return {
      id: this.site.id,
      name: this.site.name,
      date: this.dates[i]};
  }
  obj.id = this.site.id,
  obj.name = this.site.name,
  obj.date = this.dates[i];
  return obj;
 });
}

summary.component.html 在这里,我将site_info数据发送到更多子组件以对其进行图形化处理。这些本质上是“ site.component.ts”文件的孙子组件。

 <td id="td3">
   <app-precipitation [site1]="site_info"></app-precipitation>
</td>
<td id="td4">
   <app-volume [site1]="site_info"></app-volume>
</td>

2 个答案:

答案 0 :(得分:1)

您可能想尝试在site中复制ngOnInit

this.data = Object.assign({}, this.site);

答案 1 :(得分:1)

一种解决方法是复制对象:

export class SitelistComponent implements OnInit {
sites;
original;

constructor(){
}   
ngOnInit() {
    this.authService.getSites()
    .map((res:Response) => (
       res.json() 
     ))
    .subscribe(data => {
       console.log(data)
       const copies = [];
       for(let item of data) {
         copy = this.copy(item);
         copies.push(copy);
       }
       this.original = data;
       this.sites = copies;
       console.log(this.sites)
    })
  }
}

copy(object: any):any{
 return JSON.parse(JSON.stringify(obj))
}