Angular 如何在一个服务中创建一个变量,该变量从一个承诺中获取数据,并且在两个组件之间共享?

Angular 如何在一个服务中创建一个变量,该变量从一个承诺中获取数据,并且在两个组件之间共享?,angular,typescript,Angular,Typescript,我有一个使用TypeScript的Angular 2服务。我希望能够共享从该服务获得的一系列值。当一个组件对数组进行更改时,我需要它反映在另一个组件中 这是我的服务和它使用的对象的基础 export class deviceObj { device_Id:number; deviceGroup_Id:number; name:string; favoriteFlag:boolean; visibleFlag:boolean; } export class Favorite

我有一个使用TypeScript的Angular 2服务。我希望能够共享从该服务获得的一系列值。当一个组件对数组进行更改时,我需要它反映在另一个组件中

这是我的服务和它使用的对象的基础

export class deviceObj {
  device_Id:number;
  deviceGroup_Id:number;
  name:string;
  favoriteFlag:boolean;
  visibleFlag:boolean;

}

export class Favorite {
    favorite_Id: number;
    device: deviceObj;
    constructor(){this.device = new deviceObj()};

}


@Injectable()
export class FavoriteService {
    private headers = new Headers({'Content-Type': 'application/json'});
    private favoritesURL = 'URL THAT FEETCHES DATA';
    favorites: Favorite[];
    constructor(private http: Http) {

    this.getFavorites().then(favorites => this.favorites = favorites);

}

getFavorites(): Promise<Favorite[]> {
    return this.http.get(this.favoritesURL).toPromise().then(response => response.json() as Favorite[]).catch(this.handleError);


}

protected handleError2(error: Response) {
    console.error(error);
    return Observable.throw(error.json().error || 'server error');
}

private handleError(error: any): Promise<any> {
    console.error('An error occurred', error); // 
    return Promise.reject(error.message || error);
}


}
在使用服务的每个组件中,它都有自己的收藏夹数组,该数组在加载时被分配。但是,我希望服务中有一个单例变量,其中更改可以反映在两个组件中。我不知道如何用承诺做到这一点。如有需要,我乐意进一步澄清。非常感谢您的组件中的任何帮助。

//set favorites
    getFavorites(): void{
        this.favoriteService
            .getFavorites()
            .then(favorites => this.favoriteService.favorites = favorites);
    }  

// get favorite
this.favorites = this.favoriteService.favorites;//access it from service

虽然这可能是通过承诺来实现的,但我至少可以用可观察的形式来回答,如果你想了解它们的话

给定
ComponentA
ComponentB
都在查看
SharedService
以获取
SomeObject[]的数据源:

服务:

import { Injectable } from '@angular/core';
import { Observable, Observer } from 'rxjs/rx';
import 'rxjs/add/operator/share';

import { SomeObject } from './some-object';

@Injectable()
export class SomeService{
    SharedList$: Observable<SomeObject[]>;
    private listObserver: Observer<SomeObject[]>;

    private sharedList: SomeObject[];

    constructor(private http: Http){
        this.sharedList = [];
        this.SharedList$ = new Observable<SomeObject[]>(x => this.listObserver = x).share();
    }

    getList(){
        // Get the data from somewhere, i.e. http call
        this.http.get(...)
            .map(etc)
            .subscribe(res => {
                this.sharedList = res;
                this.listObserver.next(this.sharedList);
            });
        // the important part is after getting the data you want, observer.next it
    }

    addItem(item: SomeObject): void {
        this.sharedList.push(item);
        this.listObserver.next(this.sharedList);
    }
}
ComponentB
看起来类似-订阅服务上相同的
SharedList$
属性。调用服务的
getList()
方法时,它通过可观察对象(
this.listObserver.next(…)
)推送一个新的
SomeObject[]
),订阅该属性的组件将能够读取推送给它的值


编辑:在服务上公开一个
addItem
方法,组件可以调用该方法将项目推送到列表中。然后,服务将其推送到可观察对象中(
this.listObserver.next(…)
),方式与通过x其他方法(即http)获取数据时相同。

@Krenom的回答是正确的。需要在我的设置中更改一个导入


我需要从'rxjs/Rx'导入{observatable,observator};从'rxjs/Rx'导入{Observable,observator}

在组件中,从服务模型获取/设置收藏夹数组。this.favoriteService.favorites将作为singleton工作。@user32如果我创建一个get方法,它将在承诺完成之前返回。我如何制作它,使它在承诺成功的情况下返回?这似乎是复制而不是传递参考。所以在承诺完成之前,它就空了。我会试试这个,然后报告backSo,这就是我现在被卡住的地方。如何向SharedList$或listObserver添加元素?因此,如果在一个组件上,我需要添加另一个对象,我该怎么做?为了向我的服务共享的列表中添加变量,我是否需要立即保存到数据库并再次获取该列表?我希望能够在组件a
addToList(SomeObject){this.service.addToList(SomeObject)}
中执行类似的操作,然后在组件B上显示该对象。这就是拥有服务的全部意义。我可以在每个组件中单独检索这些值,而不是用其他wize。@没有确切的内容。我会更新我的答案,让你把它包括进来。不管怎样编辑,我都能让它工作。这是一个导入问题,需要从“rxjs/Rx”导入这一行
import{Observable,Observer}import { Injectable } from '@angular/core';
import { Observable, Observer } from 'rxjs/rx';
import 'rxjs/add/operator/share';

import { SomeObject } from './some-object';

@Injectable()
export class SomeService{
    SharedList$: Observable<SomeObject[]>;
    private listObserver: Observer<SomeObject[]>;

    private sharedList: SomeObject[];

    constructor(private http: Http){
        this.sharedList = [];
        this.SharedList$ = new Observable<SomeObject[]>(x => this.listObserver = x).share();
    }

    getList(){
        // Get the data from somewhere, i.e. http call
        this.http.get(...)
            .map(etc)
            .subscribe(res => {
                this.sharedList = res;
                this.listObserver.next(this.sharedList);
            });
        // the important part is after getting the data you want, observer.next it
    }

    addItem(item: SomeObject): void {
        this.sharedList.push(item);
        this.listObserver.next(this.sharedList);
    }
}
import { Component, OnInit } from '@angular/core';
import { Observable, Observer } from 'rxjs/rx';

import { SharedService } from './some.service';

import { SomeObject } from './some-object';

@Component({...})
export class CommponentA implements OnInit {
    private list: SomeObject[];

    constructor(private service: SharedService){
        this.list = [];
    }

    ngOnInit(){
        this.service.SharedList$.subscribe(lst => this.list = lst);
        this.service.getList();
    }

    private onClick(item: SomeItem): void {
        this.service.addItem(item);
    }
}