angular - Angular Ivy (8-beta):如何将 HttpClient 注入到组件中?
问题描述
我正在尝试构建一个示例应用程序来测试 Angular Ivy 与 Angular Elements 的结合,但我找不到任何关于如何在该设置中配置 DI 的信息 - 因为 app.module 被绕过了。
main.ts:
import { ɵrenderComponent as renderComponent } from '@angular/core';
import { AppComponent } from './app/app.component';
renderComponent(AppComponent);
app.module.ts:main.ts不使用这个,那么应该在哪里加载 HttpClientModule 并定义自定义元素?
import { NgModule, Injector } from '@angular/core';
import { HttpClientModule } from '@angular/common/http/http';
import { createCustomElement } from '@angular/elements';
import { AppComponent } from 'src/app/app.component';
@NgModule({
declarations: [ AppComponent ],
imports: [ HttpClientModule ],
entryComponents: [AppComponent]
})
export class AppModule {
constructor(private injector: Injector) { }
ngDoBootstrap() {
customElements.define('app-component',
createCustomElement(AppComponent, { injector: this.injector }));
}
}
app.component.ts:
import { Component, ChangeDetectionStrategy, ViewEncapsulation, Input } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject } from 'rxjs';
@Component({
selector: 'app-component',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.ShadowDom,
})
export class AppComponent {
constructor(private http: HttpClient) {
http.get<any>('someurl').subscribe(data => console.log(data));
}
}
这会导致以下异常:
错误:注射器:NOT_FOUND [HttpClient]
我已经阅读了一些关于@Component 的“deps”属性的提示,但没有找到(~8.0.0-beta.8)。我尝试添加providers: [ { provide: HttpClient } ]
到@Component,它抛出
错误:注射器:NOT_FOUND [HttpHandler]
providers: [ { provide: HttpClient, deps: [HttpHandler] } ]
仍然抛出相同的异常。
使用 Ivy 时应该在哪里配置依赖项?在此期间,应该在哪里createCustomElement
调用?
我添加了一个 github 存储库,其中包含一个最小、完整且可验证的示例:https ://github.com/markusdresch/ng-ivy-custom-element
编辑 好吧,我走得更远了。必须更明确地提供 HttpHandler(这在 @Component 中):
providers: [
{ provide: HttpClient, deps: [ HttpHandler ] },
{ provide: HttpHandler, useValue: new HttpXhrBackend({ build: () => new XMLHttpRequest() }) },
// ...
]
这样,上述错误就消失了,并且可以正常工作。但是,我仍然不确定如何注册自定义元素。
解决方案
回答我自己的问题:可以在 main.ts 中启动根注入器。这不像@NgModule 那样简单,因为还必须提供依赖项:
在 main.ts 中:
const injector: Injector = Injector.create({
name: 'root',
providers: [
{ provide: HttpClient, deps: [ HttpHandler ] },
{ provide: HttpHandler, useValue: new HttpXhrBackend({ build: () => new XMLHttpRequest() }) },
]
});
renderComponent(AppComponent, { injector: injector });
我还没有真正解决创建这样的自定义元素,除了这个黑客:
class AppComponentCustomElement extends HTMLElement {
constructor() {
super();
renderComponent(AppComponent, { injector: injector });
}
}
customElements.define('ng-ivy-custom-element', AppComponentCustomElement);
但是这种方式 @Inputs 等必须手动路由。如果我发现更有用的东西,我会继续修补和更新。
更新:根据https://juristr.com/blog/2019/05/Angular-8-and-the-Future-NGConf-2019-Roundup/#not-every-app-is-a-spa我的尝试不是被认为是一种黑客行为,但实现这一目标的正确方法。
推荐阅读
- angular - 如何使用按钮更改材料数据表中的数据(Angular)
- python - pd.DataFrame 正在覆盖列,而不是将数据保存到 pd.DataFrame
- php - 范围内的整数
- coffeescript - 如何设置 gruntfile 使编译后的文件与源文件位于同一目录中
- mips - 我的数组没有初始化怎么办?
- unity3d - Unity3D 使用 Secure Websocket for WebGL
- c++ - 如何禁用影响宏的 clang 格式设置?
- javascript - 返回数组数组
- python - Async Twitch сhatbot with Python: socket, asyncio
- r - >符号在R中的sum命令中有什么作用?