微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我正在尝试做一些可能不太常见的事情.我试图利用最好的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来说是一个非常好的改进.

那么,有什么想法吗?

解决方法:

同样,您可以在加载脚本的路径中添加一个保护,一旦加载脚本,就可以加载组件.

例如扩展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;
})

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐