簡體   English   中英

Angular Ivy(8-beta):如何將HttpClient注入組件?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM