运行时创建 Angular 5 组件,在懒加载依赖项后。

4
我正在尝试做一些可能不太常见的事情。 我想在不需要太多外部依赖的情况下充分利用Angular,但由于需求原因,我必须使用一个非常特定的日期范围选择库( this one ),但它使用了JQuery和Moment.js,以及Bootstrap的CSS(但这个已经添加了)。
在这种情况下,我可以简单地在页面中加载JQuery和Moment.js,但这似乎并不是明智的方法:打包大小会变得更大,而我必须尽量优化此应用程序。
然后,我想到了一个主意:为什么不延迟加载这些依赖项,然后再实例化我的组件呢? 这似乎是一个好方法,对吗?
我正在使用一个提供程序,让我从CDN在文档中包含脚本,并且它运行良好。 但现在,我必须以某种方式在执行时间中插入此daterangepicker组件,当两个库都加载并解决其承诺时。 当前状态: 1-我有这个父类,它在执行时间加载我的依赖项(JQuery和Moment.js):
import { Component, OnInit } from '@angular/core';
import { LibraryLazyLoader } from '../../../providers/library_lazy_loader';
import { Ng4LoadingSpinnerService } from 'ng4-loading-spinner';

@Component({
  selector: 'date-selector',
  templateUrl: './date-selector.component.html',
  styleUrls: ['./date-selector.component.css'],
  providers: [LibraryLazyLoader]
})
export class DateSelectorComponent implements OnInit {

  isLoaded = false;

  constructor(
    private libraryLoader:LibraryLazyLoader,
    private loadingSpinner:Ng4LoadingSpinnerService
  ){
    this.loadingSpinner.show();
    this.libraryLoader.loadJs('https://code.jquery.com/jquery-3.2.1.min.js')
        .subscribe(() => {
          console.log("JQuery included");
          this.libraryLoader.loadJs('https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.3/moment.min.js')
            .subscribe(() => {
              console.log("Moment.js included");
              this.loadingSpinner.hide();
              this.isLoaded = true;
            })
         })
  }

  ngOnInit() {

  }

}

2 - 它的模板就像这样:

<button>Load js</button>
<div *ngIf="isLoaded">
  <input daterangepicker>
</div>

当两个库都加载时,isLoaded布尔值应该引起视图更新,使daterangepicker指令正确加载,并允许我使用组件。问题在于这样做没有效果。虽然我不会在项目中使用它,但我非常好奇它是如何工作的,因为它可以让我们构建更加优化的页面!懒加载模块很好,但下一步是懒加载组件,我认为。如果这种方法不好,请有人纠正我,但我认为这可能是Angular的一个真正的改进。所以,有什么想法吗?

嗨@Zerok,为什么这个不起作用? - Llorenç Pujol Ferriol
1个回答

3

作为一个想法,您可以为加载脚本的路由添加守卫,一旦脚本加载完成,组件就可以加载。

例如,扩展Angular文档示例。您只需添加一个守卫来在导航到需要这些依赖项的视图之前解决它们。

@Injectable()
class TeamResolver implements Resolve<any> {

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any>|Promise<any>|any {
    return Promise.all([
import("https://code.jquery.com/jquery-3.2.1.min.js"), 
import("https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.3/moment.min.js")
])
  }
}

@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: 'team/:id',
        component: TeamCmp,
        resolve: {
          team: TeamResolver
        }
      }
    ])
  ],
  providers: [TeamResolver]
})
class AppModule {}

此外,我不确定您上面的示例有什么问题?猜测一下,我会说您看不到任何变化,这可能是因为需要让Angular再次运行周期。可以尝试:
setTimeout(() => {
   this.loadingSpinner.hide();
   this.isLoaded = true;
})

你能添加一个例子吗? - Zerok

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接