javascript - 在延迟加载其依赖项之后,在执行时创建一个 Angular 5 组件

标签 javascript angular

我正在尝试做一些可能不太常见的事情。我试图在不需要很多外部依赖项的情况下充分利用 Angular,但出于需求原因,我必须使用一个非常具体的库来选择日期范围(this one),但它使用 JQuery 和 Moment.js,以及 Bootstrap 的CSS(但是这个已经添加了)。

在这种情况下,我可以在页面中简单地加载 JQuery 和 Moment.js,但这似乎不是一个明智的方法:包大小会变得更大,我必须尽可能多地优化这个应用程序可以。

然后,我想到了一个想法:为什么不延迟加载这些依赖项,然后实例化我的组件?这似乎是个好方法,对吧?

我正在使用一个提供程序,该提供程序允许我将来自 CDN 的文档脚本包含在其中,并且运行良好。但是现在,我必须以某种方式插入这个 daterangepicker 组件,在执行时,当两个库都加载并解决了它们的 promise 时。

当前状态:

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 bool 值应该激发 View 使用正确加载的 daterangepicker 指令进行更新,并允许我使用该组件。

事实是,这行不通。虽然我不打算在项目中使用它,但我很好奇它是如何工作的,因为它可以让我们构建更优化的页面!延迟加载模块很好,但我认为下一步是延迟加载组件。如果这种方法不好,有人会纠正我,但我认为它可以是对 Angular 的一个非常好的改进。

那么,有什么想法吗?

最佳答案

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

例如扩展 Angular 文档示例。您可以在导航到需要它们的 View 之前添加一个守卫来解决依赖关系

@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;
})

关于javascript - 在延迟加载其依赖项之后,在执行时创建一个 Angular 5 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47594837/

相关文章:

javascript - 使用参数动态引用json对象

javascript - 为什么 "for (let i..."中的 i 有时表现得像 block 作用域,但其他时候却不然

javascript - IE6/IE7 中的 appendChild 不适用于现有元素

Angular 6 : Changing the code of an external library only works with 'ng serve' and not with 'ng build'

angular - 在 Angular 2 中寻找 RxJs ofObjectChanges 方法的模拟

angular - Angular IIS Cloudflare 缓存问题

javascript - 更新到 Angular 9 后,在启用 Ivy 时从子项更改父项属性时出现 ExpressionChangedAfterItHasBeenCheckedError

javascript - getCurrentPosition() 是否使用 GPS 导航?

javascript - 从一棵树到另一棵树的Vue可拖动树节点

html - 在 CSS 中更改按钮周围的蓝色框架