使数据可用于多个模块

时间:2016-10-21 18:46:52

标签: angular

所以现在我有一个像这样设置的应用程序:

AppModule
    SubModule
        Multiple Components
    SecondSubModule
        Multiple Components

我需要能够对REST API进行数据调用,并将其提供给SubModuleSecondSubModule。我正在考虑创建一个模块来包装它们并在那里调用数据,但是我无法弄清楚如何在模块中进行数据调用,或者我是否应该这样做。

如果我创建一个组件,它需要将它作为一个空标签添加到标记中,这最多是hacky。

基本上我希望这些“打包”在另一个模块下进行必要的数据调用并将其提供给其他两个模块,如下所示:

AppModule
    ParentModule
        SubModule
            Multiple Components
        SecondSubModule
            Multiple Components

此处的目标是使整个程序包可以传输并与AppModule完全分离,以便只需添加相关文件并将其添加到AppModule即可将其添加到任何其他应用程序。

在Angular 2中执行此操作的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

对于其他遇到此问题的人来说,答案就是这个。

这种思维方式非常Angular 1,在这里您可以向控制器提供数据,并通过继承将其传递下去。

虽然通过使用@Input装饰器来继承,但这里的真正解决方案是创建一个为您工作的数据服务。

您需要的工具是:

  • 可注射标题
  • HTTP
  • 可观察
  • rxjs /可观察的/的
  • rxjs / observable / share
  • rxjs /可观察的/地图

在您的数据服务中,您将导入依赖项:

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

最后,您的文件应如下所示:

data.service.ts

// 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;
        }
    }
}

my.module.ts

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 {

}

my.component.ts

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

我知道这有点长篇大论,但对那些希望做同样事情的人来说应该会有所帮助。