简体   繁体   中英

Angular service observable updating from within component

I am an Angular newbie and am stuck on a problem.

I have a problem where i have a BehaviourSubject defined within a singleton service which is being shared among 3 components. My app.ts component gets array data from an API call, then updates the BehaviourSubject using next() within the service.

The issue i am having is that when i subscribe to the service within component A, copy the data to a local empty array and then push items into that array, Component B is seeing the items appended to the array within it's subscription to paymentdataservice.ts which i don't want (I only want the 'master list').

I'm obviously doing something wrong and perhaps have misunderstood the concept of observables so i'd greatly appreciate some help as this has me stumped!

All functions are called from ngOnInit which i have excluded for code simplicity.

PaymentDataService.ts:

@Injectable()

constructor(private http: Http) { }

private _paymentlistdata = new BehaviorSubject<any>([]);
public readonly paymentlistdata = this._paymentlistdata.asObservable();

//Function to get latest Paymethodlist data and input into subject
updatePaymentListData(data) {
    this._paymentlistdata.next(data);       
}

//HTTP Call for PayMethods from API
getPayMethods() {       
        let token = localStorage.getItem('token')   
        let headers = new Headers();
        headers.append('Content-Type', 'application/json');         
        return this.http.get('https://api.xyz.com/api/paymethods?
        token='+token+'', {headers: headers})
            .map((res: Response) => res.json())
}

App.ts

App.ts needs to get the Master Payment list and store it in the service for performance purposes, so it doesn't have to pull from the API in each component.

import { PaymentDataService } from '../app/services/paymentdata.service';

constructor(private payservice : PaymentDataService) { }

//Get payment data from PaymentDataService HTTP API
getPaymentData() {
    this.payservice.getPayMethods().subscribe( 
    data => {
    if (data.Error === false) {
        this.payservice.updatePaymentListData(data); //update Behaviour 
        subject so other components can use the data locally        
    } else {
    this.router.navigate(["errorloading"]); 
    console.log (data);
    }   
},
error => {
    this.router.navigate(["errorloading"]);
    console.log (error);
});

Component A

Component A needs to take the master payment list and append some additional options for a drop down menu. These options are only applicable in this component.

import { PaymentDataService } from '../app/services/paymentdata.service';

constructor(private payservice : PaymentDataService) { }

paymentlistdatalocal = [];

//Populate paymentlist from service observable
getPaymentListData() {
    this.paymentlistsubscription = this._payservice.paymentlistdata
    .subscribe(
    data => {
        this.paymentlistdatalocal = data.Paymethods;
        this.paymentlistdatalocal.push({paymethod_id:0, paymethod_name: 'No 
        payment method selected'});
    });
}

Component B

Component B simply needs to list out the master payment list

import { PaymentDataService } from '../app/services/paymentdata.service';

constructor(private payservice : PaymentDataService) { }

paymentlistdatalocal = [];

//Populate paymentlist from service observable
getPaymentListData() {
    this.paymentlistsubscription = this._payservice.paymentlistdata
    .subscribe(
    data => {
        this.paymentlistdatalocal = data.Paymethods;
        console.log (data.Paymethods);
    });
}

A console.log from Component B shows the items appended from Component A, assuming I initialise Component A first, otherwise it only contains the 'Master List' obtained from the initial API call.

因为这是因为您this.paymentlistdatalocal = data.Paymethods引用分配变量,这意味着,当您执行此操作this.paymentlistdatalocal = data.Paymethods ,您没有在内存中进行其他操作,请尝试此方法this.paymentlistdatalocal = Object.create(data.Paymethods)与组件B相同。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM