避免在Angular 2

时间:2017-07-13 16:50:47

标签: angular reactivex

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

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

我有一个根应用程序组件,其中包含一些动态创建的div,这些div显示内容和控件,可以前后切换以查看不同的数据。前向和后向切换由我的控件控制的索引号实现。

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



<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>
&#13;
&#13;
&#13;

我创建了一个服务,我在我的app组件中调用,等待promise,然后通过我的对象数据数组迭代* ngFor。我将数据传递给我的自定义组件并传递所需的数据。像这样:

&#13;
&#13;
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;
    });
  }
}
&#13;
&#13;
&#13;

正如您所看到的,我的应用程序根组件从未使用任何数据,该数据现在缓存在一个对象中,该对象仅用于创建HTML并将数据传递给其他组件(某些内容)我的服务应该做的)。将数据从组件传递到组件也很费力。

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

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

&#13;
&#13;
<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>
&#13;
&#13;
&#13;

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

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

问题开始

在我启动Web API的时候ngOnInit()被解雇的那一刻,我如何等待异步调用在我的嵌套组件中完成,以便他们知道数据已完成加载?

如果我在视图中切换到另一个data-container div,我只需从我的contentIndex组件更改服务中的<controls>即可。但是我的data-container如何了解这种变化?

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

我想要实现并避免的事情

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

修改:在答案中的第一个建议之后,这是我的status.service.ts:

&#13;
&#13;
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();
  }
}
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

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

这将开始从服务中获取值并将其存储在observable中。您需要做的只是Subscribe来自getData()等其他子组件的数据,当行为主题具有值时,它会将它们推送到订阅它的组件。作为一个额外的好处,它将存储最后一个值,以便以后如果组件订阅,它也会接收数据。