避免通过多个子组件传递数据并在Angular 2中缓存冗余数据 [英] Avoid passing data through multiple child components and caching redundant data in Angular 2

查看:74
本文介绍了避免通过多个子组件传递数据并在Angular 2中缓存冗余数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我了解,有两种方法可以将数据从外部异步Web API调用分发到我的组件:

As far as I understood, there are 2 ways of distributing my data from external asynchronous web API calls to my components:

  • 将其从根元素传递到我的嵌套子组件
  • 通过服务进行方法调用

我有一个root应用程序组件,其中包含一些动态创建的div,这些div显示内容和控件来回切换以查看不同的数据.前进和后退切换是由我的控件正在控制的索引号实现的.

I have a root app component with some dynamically created divs that are showing content and controls to switch back and forward to see different data. That forward and backward switching is implemented by an index number that my controls are controlling.

我的第一个方法是在对象的根组件中拆分对象数据,并将其传递给我的自定义组件.像这样:

My first approach was to split the object data in my root component and pass it to my custom components. Something like this:

<controls></controls>
<div class="data-container" *ngFor="let data of data; let i = index">
  <div *ngIf="i === contentIndex">
    <general-information [generalInfo]="data.generalInformation"></general-information>
    <status-lights-container [statusInfo]="data.statusInformation"></status-lights-container>
    <textfields [textfields]="data.textFields"></textfields>
  </div>
 </div>

我创建了一个服务,在我的应用程序组件中调用该服务,等待诺言,然后通过对象数据数组使用* ngFor进行迭代.我将数据传递到我的自定义组件并传递所需的数据.像这样:

I created a service which I call in my app component, wait for the promise and then iterate with *ngFor through my array of object data. I am passing the data to my custom components and pass the needed data. Like this:

import { Data } from './models/Data';
import { StatusService } from './services/status.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  data: Data[];

  constructor(private ss: StatusService) {
  }

  ngOnInit(): void {
    this.getData();
  }

  getData(): void {
    this.ss.getStatusData().then(status => { 
      this.status = status;
    });
  }
}

如您所见,我的应用程序根组件从未使用过任何数据,现在这些数据已缓存在一个对象中,该对象仅用于创建HTML并将数据传递给我的其他组件(我的服务应该做的).同样,将数据从一个组件传递到另一个组件也很麻烦.

As you can see, my app root component never used any of the data which is now cached in an object that is only used for creating the HTML and passing the data to my other components (something that my service should do). Also passing data from component to component is laborious.

我还有一个问题,我的< status-lights-container> 只是一个容器,它还会拆分数据并将其传递给其他自定义组件.因此,我还有更多未真正使用和缓存的数据.

I have also the problem, that my <status-lights-container> is only a container, which also splits the data and passes it to other custom components. So I have even more data which is not really used and cached.

我的第二种方法是调用服务函数以获取数据并将其保存在服务的变量中.然后将数据数组的长度传递给我的根应用程序组件,并在HTML中创建该组件元素的数量.

My second approach is to call the service function to get the data and save it in a variable in the service. Then pass the length of my data array to my root app component and create this count of component elements in my HTML.

<div class="content-container" *ngFor="let index of arrayLength; let i = index">
  <div *ngIf="i === contentIndex">
    <general-information [index]="index"></general-information>
    <status-lights-container [index]="index"></status-lights-container>
    <textfields [index]="index"></textfields>
  </div>
</div>

getData(): void {
	this.ss.getStatusData().then(length => { 
	  this.arrayLength = length;
    });
}

现在,我将根据接收到的contentIndex将数据保存在服务中的数据数组中的数据加载到我的组件中.

Now I would load the data from the data array that is saved in my service into my components according to the contentIndex they are receiving.

问题开始

在我启动Web API的地方触发 ngOnInit()的那一刻,我如何等待嵌套组件中的异步调用完成,以使它们知道数据已完成加载?

At the moment of ngOnInit() is getting fired where I am starting the web API, how do I wait for the asynchronous call getting finished in my nested components so that they know that the data is finished loading?

如果我在视图中切换到另一个 data-container div,则只需从我的< controls> 更改服务中的 contentIndex 零件.但是我的 data-container 如何得知这种变化?

If I switch to another data-container div in my view I just change the contentIndex in my service from my <controls> component. But how is my data-container getting informed about this kind of change?

这通常是个好方法吗?还有其他建议吗?

Is this generally a good approach? Any other suggestions?

我想要实现和避免的事情

  • 避免将数据传递给不使用它的组件(并在其中多次缓存).
  • 尽快启动Web API调用,以从服务器获取我的数据.
  • 使加载和操作数据尽可能简单.

编辑:这是我在status.service.ts中的第一个建议:

This is my status.service.ts after first suggestions in the answers:

import pnp from "sp-pnp-js";
import { BehaviorSubject, Observable } from 'rxjs/Rx';
import { Http } from "@angular/http";
import { Injectable } from '@angular/core';
import { Status } from './../models/status';
import { STATUS } from "app/models/mock-status";

@Injectable()
export class StatusService {
  status: BehaviorSubject <Status[]> = new BehaviorSubject(null);

	constructor(private http: Http) { }

  getStatusData(): Observable<Status[]> {
    return this.http.get("app/models/mock-status")
      .map((res: Status[]) => res.json() as Status[])
      .catch((err: Response) => Observable.throw(console.log(err)));
  }

  setStatus(status: Status[]): void {
    this.status.next(status);
  }

  getStatus(): Observable <Status[]> {
    return this.status.asObservable();
  }
}

推荐答案

StatusService

@Injectable()

export class StatusService {
  status: BehaviorSubject< class[] > = new BehaviourSubject(null);

  constructor(private http: Http) {}

  getStatusData(): Observable < class[] > {
    return this.http.get(parameters)
      .map((res: class[]) => res.json() as class[])
      .catch((err: Response) => Observable.throw(console.log(err)));
  }

  setStatus(status: class[]): void {
    this.status.next(status);
  }

  getStatus(): Observable < class[] > {
    return this.status.asObservable();
  }
}

AppComponent

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  data: Data[];

  constructor(private ss: StatusService) {}

  ngOnInit(): void {
    this.getData();
  }

  getData(): void {
    this.ss.getStatusData().subscribe((status: class[]) => {
      this.ss.setStatus(status);
    });
  }
}

这将开始从服务中获取值并将其存储在可观察对象中.您所需要做的就是从其他子组件(如 getData())中进行数据的 Subscribe ,并且当Behavior主题具有值时,它将把它们推送到已订阅的组件中它.作为一项额外的奖励,它将存储最后一个值供以后使用,这样,如果某个组件随后进行订阅,它也将接收数据.

This would start fetching the values from the service and store it in the observable. All you have to do is Subscribe to the data from other child components like getData() do and when the Behaviour subject has values it will push them to components that are subscribed to it. As a added bonus, it will store the last value for later so that if a component subscribes to is afterwards it also receives the data.

这篇关于避免通过多个子组件传递数据并在Angular 2中缓存冗余数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆