【问题标题】:In Angular 8, how do I access an injected service from the browser console?在 Angular 8 中,如何从浏览器控制台访问注入的服务?
【发布时间】:2020-01-13 19:38:04
【问题描述】:

我正在使用 Angular 8。我想从我的浏览器控制台(Chrome 开发工具)访问注入服务。我可以像这样从浏览器控制台访问注入器

ng.probe(document.querySelector('app-root')).injector

我想在开发工具控制台中访问注入服务,但是当我尝试这样做时

ng.probe($0).injector.get("AbcService")

我收到以下错误。我已验证我的服务名称是正确的。我还需要做什么才能从控制台访问我的服务?

core.js:8991 Uncaught Error: StaticInjectorError(AppModule)[ActivationService]: 
  StaticInjectorError(Platform: core)[AbcService]: 
    NullInjectorError: No provider for AbcService!
    at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (core.js:8895)
    at resolveToken (core.js:9140)
    at tryResolveToken (core.js:9084)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:8981)
    at resolveToken (core.js:9140)
    at tryResolveToken (core.js:9084)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:8981)
    at resolveNgModuleDep (core.js:21208)
    at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get (core.js:21897)
    at Object.resolveDep (core.js:22268)

编辑:我试图访问的服务被导入到我的组件中

import { AbcService } from '@myapp/services';

【问题讨论】:

  • 服务被装饰成可注入的?

标签: angular service console google-chrome-devtools


【解决方案1】:

至少在 Angular 10+ 中,ng.probe 方法不再存在。你可以改用ng.getComponent:

// Get the root component
ng.getComponent(document.querySelector('app-root'));

// Any property (injected object) or method in the root component can be used:
const abcService = ng.getComponent(document.querySelector('app-root')).abcService;
abcService.getSomeAwesomeResults();

【讨论】:

  • 谢谢。那太有帮助了。 ng.getComponent 也存在于 Angular 9 中。
  • 如果您想更新页面上的所有组件,有些人可能会发现这有助于测试:document.querySelectorAll('app-YOURCOMPONENTS').forEach(component=> { ng .getComponent(component).yourPUBLICFUNCTION()})
【解决方案2】:

injector get 方法标记值可以是类引用(对象)、字符串或数值,这与您如何设置提供者有关

providers : [
  AbcService // class ref
]

你可以得到这样的服务

ng.probe(document.querySelector('app-root')).injector.get(AbcService)

但是当您运行应用程序时,您将无法从开发者控制台获得对AbcService 的引用,AbcService 在全局范围内不可用。

如果令牌只是一个字符串值

providers : [
  {provide : 'AbcService' , useClass :AbcService} , 
]

这会起作用

ng.probe(document.querySelector('app-root')).injector.get(`AbcService`)

在这两种情况下,如果令牌不存在,则会抛出错误

更新!! ??

您可以像这样将引用保存到NgModuleRef

platformBrowserDynamic()
  .bootstrapModule(AppModule).then(ref => {
    window['ngRef'] = ref; // ?
  })
  .catch(err => console.error(err));

然后可以只创建一个对象,其中包含对您要测试的所有服务的引用

import {AbcService} from './abc.service';
import {ZService} from './z.service';

export const ServRef = {
  AbcService,
  ZService
}

全局保存该对象

window['servRef'] = ServRef;

在开发者控制台中你可以这样做

ngRef.get(servRef.AbcService);
ngRef.get(servRef.ZService)

demo ⚡⚡

【讨论】:

  • 当我尝试只输入类名 ("get(AbcService)") 时,控制台抱怨没有解析服务名称 -- "Uncaught ReferenceError: AbcService is not defined"
  • 如果您像这样{provide : 'AbcService' , useClass :AbcService} 为 AbcService 设置提供程序,这将起作用,通常最常见的设置提供程序的原因是使用类 ref
  • 我记得在 angularjs 中,令牌是用于服务的字符串,这里有很多选项
  • 因为我使用的是 Angular 8(而不是 angularjs),所以规则有变化吗?例如,我的 providers 块有“providers: [AbcService, ...]”,但尝试“get(AbcService)”和“get(“AbcService”)'都失败了。
【解决方案3】:

注入的服务将作为 componentInstance 上的属性提供。如果 AbcService 被注入到 AppComponent

  export class AppComponent {  
    constructor(private abcService: AbcService) {}
  }

然后您可以通过以下方式在控制台中获取它:

ng.probe(document.querySelector('app-root')).componentInstance.abcService

【讨论】:

  • 不幸的是,它没有显示为“componentInstance”的字段。你认为这是因为它是使用“import { AbcService } from '@myapp/services';”导入的吗?
  • @Dave 是如何注入到组件中的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-10
  • 1970-01-01
  • 2020-12-06
  • 1970-01-01
  • 2022-06-11
相关资源
最近更新 更多