简体   繁体   中英

Angular 6 Service Dependency Injection

I do have a list in my ts file

component.ts

list: any[];

constructor(
    private listService: ListService
) {}

ngOnInit() {
     this.listService.getListItems()
      .subscribe(
        res => {
        this.list= res;
      },
        err => {
          console.log(err);
        }
      );
  }

passList(){
    this.listService.modifyList(this.list);
}

If I do pass my list as a parameter in a function to a service, the changes that are made inside the service on the list change the list from the component.ts file

ListService.ts

modifyList(list) {
 // operations.changes made on list are propagated in the list from component.ts
}

How?

If you pass array or object in Function as assignment.It will pass value as reference (ie both will point to same memory location). If you change in once place will reflect in another end too.

In order to avoid this. Can you take copy of the variable (immutable) and pass it.

Object:

this.list = Object.assign({}, this.list);

Array:

this.list = this.list.slice();

I would create a BehaviourSubject in the ListService and expose it asObservable . And then also create two methods on it. One( initializeList ) would get the data from API and this will trigger the initialization of the BehaviourSubject on this service. The other( modifyList ) would change the data and would trigger an update on the BehaviourSubject .

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ListService {

  url = 'https://jsonplaceholder.typicode.com/users';
  private list: BehaviorSubject<any> = new BehaviorSubject<any>(null);
  list$ = this.list.asObservable();

  constructor(private http: HttpClient) {}

  initializeList() {
    this.http.get(this.url)
      .subscribe(list => this.list.next(list));
  }

  modifyList(changedList) {
    // Make further modifications to the changedList and then:
    this.users.next(changedUsers);
  }

}

In my Component then, I would first call listService.initializeList which will initialize the list BehaviorSubject on the list. And then I would subscribe to the list$ observable .

list: any[];

constructor(
  private listService: ListService
) {}

ngOnInit() {
  this.listService.initializeList();
  this.listService.list$()
    .subscribe(
      res => {
        this.list = res;
      },
      err => {
        console.log(err);
      }
    );
}

passList() {
  this.listService.modifyList(this.list);
}

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