简体   繁体   English

在导出函数中使用 Angular 服务

[英]Use an Angular service from inside an export function

I am not sure if this is doable, but can a service be called on its methods from inside an export function that's residing in a non-Angular component (eg, just a Typescript file)?我不确定这是否可行,但是可以从驻留在非 Angular 组件(例如,只是一个 Typescript 文件)中的导出函数内部对其方法调用服务吗?

Example: supposed we have this container-managed service that's easily injectable inside Angular components.示例:假设我们有这个容器管理的服务,它可以很容易地注入到 Angular 组件中。

import { Injectable } from '@angular/core';
import { HttpClient } from "@angular/common/http";
import { Observable } from "rxjs";
import { Contact } from "@comp-store/data-model";
    
const URL = 'http://localhost:3333/api/contacts';
    
@Injectable({
  providedIn: 'root'
})
export class ContactsService {
    
  constructor(private http: HttpClient) {}

  sayHello(): string {
    return "hello there!";
  }
    
  all(): Observable<Contact[]> {
    return this.http.get<Contact[]>(URL);
  }
}

Now, suppose I have a mere Typescript file called utils.ts with this content only:现在,假设我只有一个名为utils.ts的 Typescript 文件,其中仅包含以下内容:

export const callTheService = () => {
  console.log('==> about to call the service...');
  // here, I need to get a handle on the `ContactsService` and if doable, then:
  //   - easy: call the sayHello() method to say hello, then
  //   - no easy: call the all() method to receive the returned contacts
}

With the setup above, I need to be able to issue a callTheService() call and have it deliver, is this possible?通过上面的设置,我需要能够发出callTheService()调用并让它交付,这可能吗?

Note: I know I can pass the service as a parameter but this is not the objective.注意:我知道我可以将服务作为参数传递,但这不是目标。 The objective is to have the method summon the service from its inside.目标是让该方法从其内部调用服务。

================= ==================

UPDATE: The more I think about it, the more I think it isn't doable.更新:我想得越多,我就越认为这是不可行的。 For example, I would have to write code like this inside an Angular component if I need to perform manual DI, something like:例如,如果我需要执行手动 DI,我将不得不在 Angular 组件中编写这样的代码,例如:

function  contactServiceProvider(http: HttpClient): ContactsService {
  return new ContactsService(http);
}

export const CONTACT_SERVICE = 
  new InjectionToken<ContactsService>('CONTACT_SERVICE');

@Component({
  selector: 'comp-store-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss'],
  providers: [
    {
      provide: CONTACT_SERVICE,
      useFactory: contactServiceProvider,
      deps: [HttpClient]
    }
  ]
})
export class HeaderComponent {

  constructor(@Inject(CONTACT_SERVICE) private service: ContactsService) {}

  // ...

So, having code like this inside plain Typescript files is simply not possible.因此,在普通的 Typescript 文件中包含这样的代码是不可能的。

Angular 14 has inject() - there's some good examples from netbasal - you need to initially invoke the functions that use inject from the constructor (or property initializer) of an Angular component/service Angular 14 有inject() - netbasal有一些很好的例子 - 你需要首先从 Angular 组件/服务的构造函数(或属性初始化器)调用使用inject的函数

import { inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

export function getRouteParam(key: string) {
  return inject(ActivatedRoute).snapshot.params[key];
}
@Component({
  selector: 'app-todo-page',
  templateUrl: './todo-page.component.html',
})
export class TodoPageComponent {
  id = getRouteParam('id');

  ngOnInit() {
    console.log(this.id)
  }
}

Prior to Angular 14 , no.Angular 14之前,没有。

I assume somewhere further up the call stack you'll be in Angular code so could inject the service there, and pass the service as a parameter to your util function:我假设您将在调用堆栈的更深处使用 Angular 代码,因此可以在那里注入服务,并将服务作为参数传递给您的 util 函数:

export const callTheService = (contactsService: ContactsService) => {
  contactsService.sayHello();
  // etc
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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