【发布时间】:2016-07-27 02:27:43
【问题描述】:
如何全局访问根 Angular 2 注入器的实例(例如,从浏览器控制台)。
在 Angular 1 中它是angular.element(document).injector()。
在测试和探索期间很有用,使用浏览器控制台获取注入器,然后访问不同组件、指令、服务等的实例。
【问题讨论】:
标签: angular dependency-injection
如何全局访问根 Angular 2 注入器的实例(例如,从浏览器控制台)。
在 Angular 1 中它是angular.element(document).injector()。
在测试和探索期间很有用,使用浏览器控制台获取注入器,然后访问不同组件、指令、服务等的实例。
【问题讨论】:
标签: angular dependency-injection
这是 Angular 9 的另一个版本。
在不在生产节点中的 Angular 应用程序页面上打开 JavaScript 控制台。
在页面上找到<app-root>:
root = document.querySelector("app-root");
获取注射器。 ng() helper 是一个全局变量,如果应用程序处于开发模式,则可用:
injector = ng.getInjector("app-root");
Injector 将允许您通过其类名获取服务。不幸的是,我不知道 Angular 服务类是否或如何通过 window 命名空间获得。
所以我们的下一个尝试是从页面上已经可见元素的组件中获取服务。
appComponent = ng.getComponent(root)
这样您就可以访问任何AppComponent 变量,例如您的应用可能具有“UserService”。
appComponent.userService
UserService {http: HttpService, userSubject: BehaviorSubject}
现在你可以从控制台调用服务了:
appComponent.userService.userSubject.value.userEmail
mikko@capitalgram.com
您还可以访问不是应用程序根的组件,并访问绑定到它们的服务。首先,我们需要导航到组件出现的页面。这将触发 UI 中的实际转换。
await appComponent.router.navigate(["/another-page"])
现在您可以通过标签名称获取任何可见组件:
elem = document.querySelector("app-my-component")
component = ng.getComponent(elem)
你可以看到它的服务:
MyComponent(envService, http, sanitizer);
您可以在所有用户令牌、会话等就位的情况下戳它们:
component.envService.getConfigValue()
【讨论】:
在 Angular v.4.x.x 中,根注入器位于 PlatformRef 上。你可以这样访问它:
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
// create a platform
let platform = platformBrowserDynamic();
// save reference to the global object
window['rootInjector'] = platform.injector;
// boostrap application
platform.bootstrapModule(AppModule);
或者在任何这样的组件中:
export class AppComponent {
constructor(platform: PlatformRef) {
console.log(platform.injector);
但是root 注入器非常没用。它主要包含编译器和平台特定的数据和帮助器:
[
"InjectionToken Platform ID",
"PlatformRef_",
"PlatformRef",
"Reflector",
"ReflectorReader",
"TestabilityRegistry",
"Console",
"InjectionToken compilerOptions",
"CompilerFactory",
"InjectionToken Platform Initializer",
"PlatformLocation",
"InjectionToken DocumentToken",
"InjectionToken Platform: browserDynamic",
"InjectionToken Platform: coreDynamic",
"InjectionToken Platform: core"
]
您可能正在寻找AppModule 注射器,您可以像这样得到:
platform.bootstrapModule(AppModule).then((module) => {
window['rootInjector'] = module.injector;
});
您可以从中提取ApplicationRef 或root ComponentRef:
platform.bootstrapModule(AppModule).then((module) => {
let applicationRef = module.injector.get(ApplicationRef);
let rootComponentRef = applicationRef.components[0];
});
另外,如果 Angular 在开发模式下运行,您可以像这样获得 AppModule 或延迟加载的 NgModule 注入器:
ng.probe($0).injector.view.root.ngModule
【讨论】:
ng.probe($0).injector.view.root.ngModule 这样你就可以得到AppModule 或者延迟加载的NgModule 注入器
enableProdMode()
It can be useful during testing and exploration,所以这会很有帮助:)
您必须在启动应用程序后将其设置为服务:
export var applicationInjector: Injector;
bootstrap([AppComponent]).then((componentRef: ComponentRef) => {
applicationInjector = componentRef.injector;
});
然后您可以将其导入应用程序的其他部分:
import {applicationInjector} from './bootstrap';
查看这个问题了解更多详情:
编辑
您可以将ApplicationRef 注入组件并通过它访问根注入器:
@Component({
(...)
})
export class SomeComponent {
constructor(private app:ApplicationRef) {
var rootInjector = app.injector;
}
}
您需要利用依赖注入来获取它。
【讨论】:
ComponentRef 的实例是否由 Angular 2 保存在任何地方并在全球范围内可用(例如 ng.core.rootComponent())?无论如何,手动保存它比 Angular 1 中可用的工作量更大,但仍然没问题。
ApplicationRef 注入您的组件并访问根注入器。无需手动保存 ;-) 我相应地更新了我的答案。
ApplicationRef 没有公共属性 injector;显然它是私有的。