[英]How to render and load dynamically a component with Angular 9 (Ivy)
[英]Angular Ivy (8-beta): How to Inject HttpClient into Component?
我正在嘗試構建一個示例應用程序來測試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] } ]
仍然會拋出相同的異常。
使用常春藤時應該在哪里配置依賴項? 在它的時候,應該在哪里調用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 });
我還沒有真正解決過創建這樣的自定義元素的問題,除了這個hack:
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我的嘗試不是被認為是黑客,但實現這一目標的正確方法。
要在任何組件中提供模塊依賴性,請在同一組件文件中定義模塊,如下所示。
@NgModule({
declarations: [
AppComponent
],
imports: [
CommonModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
}
這里的ivy renderer
從app模塊解析HttpClient。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.