首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >正确理解angular14中的inject - inject()必须从注入上下文中调用

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

Stack Overflow用户
提问于 2022-06-05 22:17:56
回答 2查看 2.8K关注 0票数 3

我正在尝试学习角14的变化,特别是inject()特性,我可以将模块注入函数,并且不需要为此创建特殊的服务。但我想我出了点问题。

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

这是我的messages.ts文件:

代码语言:javascript
运行
复制
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
  });
};

我得到了以下错误:

代码语言:javascript
运行
复制
Error: Uncaught (in promise): Error: NG0203: inject() must be called from an injection context (a constructor, a factory function or a field initializer)

好吧..。当我试图拥有一个辅助功能来获得路径仿生线时,我遇到了一个问题:

代码语言:javascript
运行
复制
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的新手,我认为注射可以让我做到这一点。否则对我没什么用。

现在我把它作为一项服务..。

代码语言:javascript
运行
复制
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?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-06-06 03:22:46

正如在答案中提到的,它只能在DI系统实例化依赖项时初始化。您可以通过创建高阶函数来解决这一问题。

代码语言:javascript
运行
复制
export const snackMsgSuccess = () => {
  const toaster = inject(ToastrService);
  return (msg: string,title?: string)=>{
    toaster.success(msg, title, {
      easeTime: 1000
    });
  }
};

component.ts

代码语言:javascript
运行
复制
snackMsgSuccess = snackMsgSuccess();


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

更新角14.1

在这个版本中,可以使用runInContext API在函数体内部使用注入函数。

获取更多信息

票数 3
EN

Stack Overflow用户

发布于 2022-09-26 19:27:06

由于角14.1,您可以使用runInContext

简单的例子:

代码语言:javascript
运行
复制
class Foo {
    constructor(private injector: EnvironmentInjector) {
        setTimeout(() => {
            // can't inject()

            this.injector.runInContext(() => {
                inject(MyService) // fine
            });
        }, 1000);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72511481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档