在 Angular 8 中,如何从浏览器控制台访问注入的服务?

Posted

技术标签:

【中文标题】在 Angular 8 中,如何从浏览器控制台访问注入的服务?【英文标题】:In Angular 8, how do I access an injected service from the browser console? 【发布时间】: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';

【问题讨论】:

服务被装饰成可注入的? 【参考方案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”)'都失败了。 你试过ng.probe($0).componentInstance吗?【参考方案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 是如何注入到组件中的?

以上是关于在 Angular 8 中,如何从浏览器控制台访问注入的服务?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Angular 1.5 中从父控制器访问组件方法

如何使用AngularJS在浏览器控制台中访问$ scope变量?

JAX-RS (jersey) -> Angular.js 通过 REST

如何使用 Angular JS 从外部范围访问数组值

如何 在 VSCode集成 angular2/4 插件

从 Angular 表达式访问窗口