Angular 6 服务依赖注入

Posted

技术标签:

【中文标题】Angular 6 服务依赖注入【英文标题】:Angular 6 Service Dependency Injection 【发布时间】:2019-03-04 03:24:47 【问题描述】:

我的 ts 文件中有一个列表

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

如果我确实将我的列表作为参数在函数中传递给服务,则在列表中内部服务所做的更改会将列表从component.ts 文件

ListService.ts

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

怎么做?

【问题讨论】:

如果,例如,在我设置的服务的 modifyList() 函数中 list = [ ] ,那么来自 component.ts 的列表也将变为空。 这是正常行为,因为数组和对象是通过引用传递的。如果要在服务内部进行不影响组件的修改,则需要在将列表传递给服务之前克​​隆列表 好的,我明白了,这可能是因为list 数组中的对象与modifyList() 参数list 共享相同的引用。它们是两个独立的数组,但对对象的引用是相同的。 由于在 JS 中,像数组和对象这样的复杂类型是通过引用传递的,所以在您的 modifyList(list) 函数中执行 list = [ ] 本质上也会使组件中的 list 也为空。虽然这不是推荐的方式,因为它会更改您的应用程序的状态,您将无法推理。 【参考方案1】:

我会在ListService 中创建一个BehaviourSubject 并公开它asObservable。然后也在上面创建两个方法。一个(initializeList)将从 API 获取数据,这将触发该服务上 BehaviourSubject 的初始化。另一个(modifyList) 将更改数据并触发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);
  


然后,在我的组件中,我将首先调用listService.initializeList,它将初始化列表中的listBehaviorSubject。然后我会订阅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);

【讨论】:

【参考方案2】:

如果您在函数中传递数组或对象作为赋​​值。它将值作为引用传递(即两者都将指向相同的内存位置)。如果你在一次地方改变也会反映在另一端。

为了避免这种情况。您可以复制变量(不可变)并传递它吗?

对象:

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

数组:

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

【讨论】:

以上是关于Angular 6 服务依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

当我在 HttpInterceptor 类中注入使用 HttpClient 的服务时,Angular 6 进入循环依赖的无限循环

Angular依赖注入小解

Angular依赖注入机制与服务的作用范围

如何在 Angular-Fullstack 生成的 Angular 1.5 组件中注入依赖项

Angular依赖注入介绍

Angular 2 - 如何将依赖项注入到自定义类中,该类不是组件并且不作为服务公开