正确理解 angular14 中的注入 - 必须从注入上下文中调用注入()

分享于2022年07月17日 angular angular14 inject 问答
【问题标题】:正确理解 angular14 中的注入 - 必须从注入上下文中调用注入()(properly understanding inject in angular14 - inject() must be called from an injection context)
【发布时间】:2022-06-16 22:16:16
【问题描述】:

我正在尝试学习 angular 14 的变化,尤其是 inject() 功能,我可以将模块注入到函数中,我不需要为此创建特殊服务.. 但我想我得到了出了点问题。

我正在尝试创建一些静态函数来使用包 ngx-toastr 发送零食消息,但这个包与我的问题无关。如何正确实现显示零食消息的功能,同时向它们注入它们需要操作的所需模块。

这是我的 messages.ts 文件:

import {inject} from '@angular/core';
import {ToastrService} from 'ngx-toastr';


export const snackMsgSuccess = (msg: string, title?: string) => {
  const toaster = inject(ToastrService);
  toaster.success(msg, title, {
    easeTime: 1000
  });
};


export const snackMsgInfo = (msg: string, title?: string) => {
  const toaster = inject(ToastrService);
  toaster.info(msg, title, {
    easeTime: 1000
  });
};

export const snackMsgWarn = (msg: string, title?: string) => {
  const toaster = inject(ToastrService);
  toaster.warning(msg, title, {
    easeTime: 1000
  });
};


export const snackMsgError = (msg: string, title?: string) => {
  const toaster = inject(ToastrService);
  toaster.error(msg, title, {
    easeTime: 1000
  });
};

我收到以下错误:

Error: Uncaught (in promise): Error: NG0203: inject() must be called from an injection context (a constructor, a factory function or a field initializer)

嗯...我在尝试使用支持功能来获取路由参数之前遇到了问题:

export const routeParam$ = (key: string) => {
  const activatedRoute = inject(ActivatedRoute);

  return activatedRoute.params.pipe(
    pluck(key),
    filter(r => r !== null),
    distinctUntilChanged()
  );
};

而我只能在带有 task: Observable<string> = routeParam$('task'); 的组件中用作字段初始值设定项

嗯,错误信息很清楚......但仍然......我是 angular14 的新手,我认为注入可以让我这样做。否则对我没那么有用。

现在我将它作为服务移动..

import {Injectable} from '@angular/core';
import {ToastrService} from 'ngx-toastr';

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

  constructor(private toaster: ToastrService) {
  }

  public snackMsgSuccess = (msg: string, title?: string) => {
    this.toaster.success(msg, title, {
      easeTime: 1000
    });
  };


  public snackMsgInfo = (msg: string, title?: string) => {
    this.toaster.info(msg, title, {
      easeTime: 1000
    });
  };

  public snackMsgWarn = (msg: string, title?: string) => {
    this.toaster.warning(msg, title, {
      easeTime: 1000
    });
  };


  public snackMsgError = (msg: string, title?: string) => {
    this.toaster.error(msg, title, {
      easeTime: 1000
    });
  };
}

但这是实现它的唯一方法吗?即使在 angular14 中?


【解决方案1】:

如答案中所述,它只能在 DI 系统实例化依赖项期间初始化。您可以通过创建高阶函数来解决此问题。

export const snackMsgSuccess = () => {
  const toaster = inject(ToastrService);
  return (msg: string,title?: string)=>{
    toaster.success(msg, title, {
      easeTime: 1000
    });
  }
};

component.ts

snackMsgSuccess = snackMsgSuccess();


ngOnInit(){
   this.snackMsgSuccess('Success','Test');
}