仅在将所有脚本加载到Resolver中后,才如何导航到Angular组件?

时间:2018-10-26 13:02:30

标签: javascript angular typescript observable angular-resolver

我有一个任务要在组件加载之前从Amazon S3存储桶加载3个脚本,因为它使用了此脚本中的逻辑。因此,我有一个解析器,该脚本将脚本标签添加到 HEAD

private scripts: ScriptModel[] = [];
private envScripts: ScriptModel[];

constructor(
    private appState: AppState
) {
    // empty
}

public resolve() {
    console.log('Resolver');
    const environment = this.appState.restore('environment');


    forkJoin(this.load(environment))
        .subscribe(
            () => { /* empty */ console.log('Scripts loaded'); },
            (error: any) => { console.log(`Error to load scripts for preview: `, error); }
        );
}

public load(env: string) {
    this.envScripts = ScriptStore[env].map((_script: ScriptModel) => ({ name: _script.name, src: _script.src, loaded: _script.loaded }));
    const scripts: ScriptModel[] = this.envScripts.map((_script: ScriptModel) => this.loadScript(_script));

    return scripts;

}

public loadScript(script: ScriptModel) {

    return Observable.create((observer: Observer<ScriptModel>) => {

        const existingScript = this.scripts.find((_script: ScriptModel) => _script.name === script.name);

        if (!!existingScript && existingScript.loaded) {

            observer.next(existingScript);
            observer.complete();

        } else {

            this.scripts = [...this.scripts, script];

            const scriptElement = document.createElement('script');

            scriptElement.type = 'text/javascript';
            scriptElement.src = script.src;

            scriptElement.onload = () => {

                script.loaded = true;
                observer.next(script);
                observer.complete();
            };

            scriptElement.onerror = () => {

                observer.error(`Couldn't load script ${script.name}, ${script.src}`);

            };

            document.querySelector('head').appendChild(scriptElement);

        }

    });
}

ScriptStore根据环境名称包含脚本,ScriptModel是描述其外观的接口:

export interface ScriptModel {
name: string;
src: string;
loaded: boolean;

}

我有一个问题,有时组件中的代码会引发错误,这些附加脚本的功能未定义。据我了解,这是因为组件中的代码会在加载这些脚本之前执行。在组件中,一些代码开始在构造函数中工作,而主函数在 ngOnInit 中调用。但是在解析器完成之前,不应加载该组件。我需要在解析器中返回一些 Observable / Promise 吗?我应该如何正确地做呢?仅当所有脚本都已加载时,解析程序才必须完成。我使用Observables来控制是否加载了脚本,而在解析器之前,它是具有诺言的服务,但是它也会引发相同的错误。

0 个答案:

没有答案