所以现在我有一个像这样设置的应用程序:
AppModule
SubModule
Multiple Components
SecondSubModule
Multiple Components
我需要能够对REST API进行数据调用,并将其提供给SubModule
和SecondSubModule
。我正在考虑创建一个模块来包装它们并在那里调用数据,但是我无法弄清楚如何在模块中进行数据调用,或者我是否应该这样做。
如果我创建一个组件,它需要将它作为一个空标签添加到标记中,这最多是hacky。
基本上我希望这些“打包”在另一个模块下进行必要的数据调用并将其提供给其他两个模块,如下所示:
AppModule
ParentModule
SubModule
Multiple Components
SecondSubModule
Multiple Components
此处的目标是使整个程序包可以传输并与AppModule
完全分离,以便只需添加相关文件并将其添加到AppModule
即可将其添加到任何其他应用程序。
在Angular 2中执行此操作的正确方法是什么?
答案 0 :(得分:2)
对于其他遇到此问题的人来说,答案就是这个。
这种思维方式非常Angular 1,在这里您可以向控制器提供数据,并通过继承将其传递下去。
虽然通过使用@Input
装饰器来继承,但这里的真正解决方案是创建一个为您工作的数据服务。
您需要的工具是:
在您的数据服务中,您将导入依赖项:
// App Imports
import { Injectable } from '@angular/core';
import { Headers, Http } from "@angular/http";
import {Observable} from 'rxjs/Observable';
// RXJS Imports
import 'rxjs/observable/of';
import 'rxjs/add/operator/share';
import 'rxjs/add/operator/map';
然后你需要一个可注射的装饰器
@Injectable
然后你需要你的班级
export class DataService {
接下来是构造函数
// Constructor
constructor(private http: Http) { }
现在我们需要一些变量
// Variables
private data: any = null;
private observable: Observable<any>;
private headers = new Headers({"Content-Type": "application/json"});
从REST / JSON API 检索数据后, data
将保留我们的数据
observable
将保存我们的observable,外部调用将订阅的对象(这是神奇的部分)
headers
只保留我们用来发送http请求的标头。
现在我们需要定义获取数据的函数
// Returns data
getData() {
现在将出现一种算法,根据服务状态返回正确的对象。
// If we already have data
if (this.data){
// Return the data
return Observable.of(this.data);
} else if (this.observable){
// Otherwise if we have an observable, return it
return this.observable;
} else {
// Otherwise get the data
this.observable = this.http.get("/api/myApiClass", {headers: this.headers})
.map( response => {
// Clear the observable
this.observable = null;
// If the call failed
if (response.status == 400) {
// Return false
return false
} else if (response.status == 200){
// Otherwise set the data
this.data = response.json().data;
// And return the response
return this.data
}
})
.share();
// Return the observable to be subscribed to
return this.observable;
}
注意那边的.share()
右边。这是确保我们只进行一次HTTP调用的最后一块魔法。
现在我们需要在包含将使用此服务的组件的模块中提供此服务。
首先,将数据服务导入您的模块
import { DataService } from "../../services/data.service";
现在在您的提供商中声明它
providers: [ DataService ]
现在所有子组件都可以作为单身人员访问该服务。
现在,在将调用此数据服务的组件中,您将导入服务,确保包含OnInit:
import {Component,OnInit} from '@angular/core';
import { DataService } from "../services/data.service";
在构造函数中定义数据服务
constructor(private dataService: DataService){};
现在最后,订阅数据服务中包含的observable:
ngOnInit(){
this.dataService.getData().subscribe(data => {
this.data = data;
});
}
最后,您的文件应如下所示:
// App Imports
import { Injectable } from '@angular/core';
import { Headers, Http } from "@angular/http";
import {Observable} from 'rxjs/Observable';
// RXJS Imports
import 'rxjs/observable/of';
import 'rxjs/add/operator/share';
import 'rxjs/add/operator/map';
@Injectable()
export class DataService{
// Constructor
constructor(private http: Http) { }
// Variables
private data: any = null;
private observable: Observable<any>;
private headers = new Headers({"Content-Type": "application/json"});
// Returns data
getData() {
// If we already have data
if (this.data){
// Return the data
return Observable.of(this.data);
} else if (this.observable){
// Otherwise if we have an observable, return it
return this.observable;
} else {
// Otherwise get the data
this.observable = this.http.get("/api/myApiClass", {headers: this.headers})
.map( response => {
// Clear the observable
this.observable = null;
// If the call failed
if (response.status == 400) {
// Return false
return false
} else if (response.status == 200){
// Otherwise set the data
this.data = response.json().data;
// And return the response
return this.data
}
})
.share();
// Return the observable to be subscribed to
return this.observable;
}
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DataService } from "../../services/data.service";
@NgModule({
imports: [
CommonModule
],
declarations: [],
exports: [],
providers: [ DataService ]
})
export class MyModule {
}
import {Component,OnInit} from '@angular/core';
import { DataService } from "../services/data.service";
@Component({
selector: 'my-selector',
template: require('./my.component.html')
})
export class MyComponent{
constructor(private dataService: DataService){};
data: any;
ngOnInit(){
this.dataService.getData().subscribe(data => {
this.data= data;
});
}
}
我知道这有点长篇大论,但对那些希望做同样事情的人来说应该会有所帮助。