How can I create a variable in a service that gets its data from a promise yet is shared between two components?

后端 未结 3 349
天涯浪人
天涯浪人 2021-01-15 19:41

I have a service in an Angular 2 using TypeScript. I want to be able to share an array of values that I get from that service. when one component makes a change to the array

3条回答
  •  北恋
    北恋 (楼主)
    2021-01-15 20:43

    While it can probably be done with Promises, I can answer in the form of Observables at the very least, if you're of a mind to read about them...

    Given ComponentA and ComponentB both looking at a SharedService for their source of SomeObject[] data:

    The service:

    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;
        private listObserver: Observer;
    
        private sharedList: SomeObject[];
    
        constructor(private http: Http){
            this.sharedList = [];
            this.SharedList$ = new Observable(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);
        }
    }
    

    Components then have:

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

    ComponentB would look similar - subscribing to the same SharedList$ property on the service. When the service's getList() method is called, and it pushes a new SomeObject[] through the observables (this.listObserver.next(..)), the components subscribed to that property will be able to read the value pushed to it.

    Edit: Exposed an addItem method on the service that the components can call to push items to the list. The service then pushes it through the observable, (this.listObserver.next(...)) in the same style as when getting the data through x other method (i.e. http).

提交回复
热议问题