#angular
#angular
Вопрос:
Я пытаюсь создать пример приложения для тестирования Angular Ivy в сочетании с элементами Angular, но я не могу найти никакой информации о том, как 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]
Я прочитал несколько подсказок о свойстве ‘deps’ для @Component, но оно не найдено (~ 8.0.0-бета.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() }) },
// ...
]
Таким образом, вышеуказанные ошибки устранены, и это работает. Однако я все еще не уверен, как зарегистрировать пользовательский элемент.
Комментарии:
1. Мне также любопытно, как бы вы использовали другой вложенный компонент angular… никаких блоков объявления, верно?
Ответ №1:
Чтобы ответить на мой собственный вопрос: можно запустить корневой инжектор в 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 моя попытка не считается взломом, но это правильный способ добиться этого.
Ответ №2:
Чтобы обеспечить зависимости модуля в любом компоненте, определите модуль в том же файле компонента, как показано ниже.
@NgModule({
declarations: [
AppComponent
],
imports: [
CommonModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
}
Здесь ivy renderer
разрешите HttpClient из модуля приложения.