【问题标题】:Angular 6 Service Dependency InjectionAngular 6 服务依赖注入
【发布时间】: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 也为空。虽然这不是推荐的方式,因为它会更改您的应用程序的状态,您将无法推理。

标签: angular service dependencies components code-injection


【解决方案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();

    【讨论】:

      猜你喜欢
      • 2019-04-02
      • 2018-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多