我在 Angular 16 中遇到服务问题

问题描述 投票:0回答:1

我正在使用 Angular 16 进行一个涉及使用巴尔干族谱的项目,但我在服务中遇到了问题

这是发出值的函数,正在使用 Angular Core 中的 HttpClient:

this.httpClient.get(url, { headers }).subscribe(
          {
            next: res => {
              console.log(res);
              this.apiResponse = res;
              this.cdr.detectChanges();
              this.zone.run(()=>{
                this.specimenData.$specimens.emit(res);
              });
              this.specimens = this.apiResponse;
            },
            error: err => {
              console.log(err);
            }
          }
        );

如您所见,我尝试查看响应的内容及其用我需要发出的数据定义的内容。 我还尝试让 Angular 检测变化并向该区域执行发射操作,但没有任何效果!当我订阅这个函数中的服务时,我刚刚得到了未定义的信息(这个函数在另一个组件上):

this.specimenData.$specimens.subscribe(value => { this.data = value });
    if (this.data != undefined) {
      var specimens = [];
      const tree = document.getElementById('tree');
      if (tree) {
        var family = new FamilyTree(tree, {
          nodeBinding: {
            field_0: "name",
            img_0: "img"
          },
        });

        family.load([
          { id: 1, pids: [2], name: "Amber McKenzie", gender: "female", img: "https://cdn.balkan.app/shared/2.jpg" },
          { id: 2, pids: [1], name: "Ava Field", gender: "male", img: "https://cdn.balkan.app/shared/m30/5.jpg" },
          { id: 3, mid: 1, fid: 2, name: "Peter Stevens", gender: "male", img: "https://cdn.balkan.app/shared/m10/2.jpg" },
          { id: 4, mid: 1, fid: 2, name: "Savin Stevens", gender: "male", img: "https://cdn.balkan.app/shared/m10/1.jpg" },
          { id: 5, mid: 1, fid: 2, name: "Emma Stevens", gender: "female", img: "https://cdn.balkan.app/shared/w10/3.jpg" }
        ]);
      }
    } else {
      console.log("im showing from tree component"+this.data);
    }

正如您所看到的,当我从服务的订阅方法传递值时,它传递了一个未定义的值,并且控制台以其他方式显示消息。 很奇怪,因为我在我的应用程序中使用其他服务,它们工作正常,甚至其中一些服务发出像这样的 api 响应,这是他的文件中该服务的代码:

import { EventEmitter, Injectable } from '@angular/core';

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

  constructor() { }

  $specimens = new EventEmitter<any>();
}

我尝试将“可注入”更改为“注入”,但没有成功,我还尝试将服务添加到 NgModule 中的提供者,但什么也没有,如果有人对发生的事情有想法或线索,请告诉我,如果您需要更多信息请随时向我索取。

angular angular-services
1个回答
0
投票

一些可以解决您的问题的观察结果。

EventEmitter
用于父/子组件之间的通信,而不是服务上的通信。

如果您在服务中处理应用程序状态,请使用主题 (

Subject
BehaviorSubject
AsyncSubject
ReplaySubject
),具体取决于 情况。

您不应该在服务中

subscribe
observables
,有一些例外,但尽量不要这样做,相反,您的服务功能应该返回一个
observable
,以便任何组件都可以对可能发生的任何更改做出反应服务(通过使用
next()
)。

避免使用

var
,坚持使用
let
const
,具体取决于变量稍后是否会更改。

使用

Angular
DOM
进行交互,不要使用原生
javascript
,您可以使用
ViewChild

鉴于这些建议,您可以将当前代码重构如下:

服务

@Injectable({...})
export class SpecimensService {
  //Just for demo purposes, I am assuming the data is an array of type yourTypeGoesHere
  private _specimen$ = new BehaviorSubject<yourTypeGoesHere[]>([]);

  fetchSpecimens(): void {
    this._specimen$ = this.get(...);
  }

  getSpecimens(): Observable<yourTypeGoesHere[]> {
    return this._specimen$.asObservable();
  }
}

组件 HTML

<div #tree id="tree" class="...">
  ...
  ...
</div>

组件

@Component({...})
export class MyComponent implements OnInit {
   // this is one way of taking reference from an HTML element
   // again, for demo purposes, I am using a div here
   @ViewChild('tree') tree!: ElementRef<HTMLDivElement>; 
   private _specimenService = inject(SpecimenService);

   ngOnInit(): void {
     // set the data to the service's subject
     this._specimenService.fetchSpecimen();
 
     // retrieve the data
     this._specimenService.getSpecimens().subscribe((data) => {
      const specimens = [];
      
      if (this.tree) {
       //logic goes here...
       //...
      }
     });
   }
}
© www.soinside.com 2019 - 2024. All rights reserved.