Я пытаюсь создать NgModuleRef<AppModule>
, чтобы преобразовать некоторые из моих компонентов в форматы, отличные от HTML.
Мне удалось создать объект PlatformRef
, однако, когда я звоню bootstrapModule(AppModule)
на этом объекте я получаю сообщение об ошибке:
"Ошибка: не предоставлена реализация ResourceLoader. Не удается прочитать URL" app.component.html ""
Возможно, мне следует добавить регистрацию DI ResourceLoader
в месте, отличном от extraProviders
, но я не знаю, где именно ...
Код:
import { ResourceLoader } from '@angular/compiler';
import { Compiler, CompilerFactory, Injectable, StaticProvider, Type } from '@angular/core';
import { platformDynamicServer } from '@angular/platform-server';
import { AppComponent } from './app/app.component';
import { AppModule } from './app/app.module';
export function createCompiler(compilerFactory: CompilerFactory) {
return compilerFactory.createCompiler();
}
async function generate<M>(moduleType: Type<M>) {
try {
const extraProviders: StaticProvider[] = [
{ provide: ResourceLoader, useClass: ResourceLoaderImpl, deps: [] },
{ provide: Compiler, useFactory: createCompiler, deps: [CompilerFactory] },
];
const platformRef = platformDynamicServer(extraProviders);
const moduleRef = await platformRef.bootstrapModule(moduleType); // <<< BREAKS HERE
const appComponent = moduleRef.injector.get(AppComponent);
console.info(appComponent.title.toString());
} catch (error) {
throw new Error(error.toString());
}
}
generate(AppModule)
.then(message => console.info({ message }))
.catch(error => console.error({ error }));
Код класса ResourceLoaderImpl
копируется в письмо из @angular/platform-browser-dynamic
(src\resource_loader\resource_loader_impl.ts
):
@Injectable()
export class ResourceLoaderImpl extends ResourceLoader {
get(url: string): Promise<string> {
let resolve: (result: any) => void;
let reject: (error: any) => void;
const promise = new Promise<string>((res, rej) => {
resolve = res;
reject = rej;
});
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'text';
xhr.onload = function() {
// responseText is the old-school way of retrieving response (supported by IE8 & 9)
// response/responseType properties were introduced in ResourceLoader Level2 spec (supported
// by IE10)
const response = xhr.response || xhr.responseText;
// normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
let status = xhr.status === 1223 ? 204 : xhr.status;
// fix status code when it is 0 (0 status is undocumented).
// Occurs when accessing file resources or on Android 4.1 stock browser
// while retrieving files from application cache.
if (status === 0) {
status = response ? 200 : 0;
}
if (200 <= status && status <= 300) {
resolve(response);
} else {
reject(`Failed to load ${url}`);
}
};
xhr.onerror = function() { reject(`Failed to load ${url}`); };
xhr.send();
return promise;
}
}