Angular库(UMD)和动态加载问题

问题描述 投票:0回答:1

我有一个包含加载按钮的Angular应用程序。单击加载按钮时,它将呈现远程UMD库。

我第一次单击加载按钮时使用SystemJS导入库时出现以下错误:

core.js:15714 ERROR Error: Uncaught (in promise): TypeError: Cannot read property '__source' of undefined
TypeError: Cannot read property '__source' of undefined
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:8984)

当我第二次单击时,没有错误,库正确呈现。

我在我的代码中将问题缩小到这个语句:

export class PostService {
  constructor(private httpClient: HttpClient) { }

如果我删除httpClient服务,库正确加载但我没有访问HttpClient。

如果有人知道为什么我的代码行为那样,我将不胜感激!

以下是我的设置:

我的远程库中有以下组件:

 sample-pack-lib.component
   |_db2-chart2.component
      |_post.service

库'samplePack-lib'使用'ng build samplePack-lib'编译,我通过快速服务器公开了以下输出:

dist/sample-pack-lib/sample-pack-lib.umd.js

DB2的chart2.component.ts:

import { Component, ElementRef, ViewChild, AfterViewInit, OnInit } from '@angular/core';
import * as vis from 'vis';
import { Graph2d, PointItem } from 'vis';
import { PostService } from '../services/post.service';

@Component({
  selector: 'izoa-db2-chart2',
  templateUrl: './db2-chart2.component.html',
  styleUrls: ['./db2-chart2.component.scss']
})
export class Db2Chart2Component implements OnInit {

  @ViewChild('vizchart') vizchart: ElementRef;

  data: Row[] = [];

  constructor(private postService: PostService) { }

post.service.ts:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { map } from 'rxjs/operators';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})

export class PostService {
  constructor(private httpClient: HttpClient) { }

样品包-lib.module.ts:

import { NgModule } from '@angular/core';
import { SamplePackLibComponent } from './sample-pack-lib.component';
import { Db2Chart2Component } from './db2-chart2/db2-chart2.component';
import { Db2Chart1Component } from './db2-chart1/db2-chart1.component';
// import { HttpClientModule } from '@angular/common/http';


import {
  MatButtonModule,
  MatCardModule,
  MatMenuModule,
  MatToolbarModule,
  MatIconModule,
  MatSidenavModule,
  MatGridListModule,
  MatListModule
} from '@angular/material';


@NgModule({
  declarations: [
    Db2Chart2Component,
    SamplePackLibComponent,
    Db2Chart1Component
  ],
  imports: [
    // HttpClientModule,
    MatButtonModule,
    MatMenuModule,
    MatCardModule,
    MatToolbarModule,
    MatIconModule,
    MatSidenavModule,
    MatGridListModule,
    MatListModule
  ],
  exports: [
    SamplePackLibComponent,
    Db2Chart2Component,
    Db2Chart1Component
  ]
})
export class SamplePackLibModule { }

公共api.ts

import { NgModule } from '@angular/core';
import { SamplePackLibComponent } from './sample-pack-lib.component';
import { Db2Chart2Component } from './db2-chart2/db2-chart2.component';
import { Db2Chart1Component } from './db2-chart1/db2-chart1.component';
// import { PostService } from './services/post.service';
// import { HttpClientModule } from '@angular/common/http';


import {
  MatButtonModule,
  MatCardModule,
  MatMenuModule,
  MatToolbarModule,
  MatIconModule,
  MatSidenavModule,
  MatGridListModule,
  MatListModule
} from '@angular/material';


@NgModule({
  declarations: [
    Db2Chart2Component,
    SamplePackLibComponent,
    Db2Chart1Component
  ],
  // providers: [PostService],
  imports: [
    // HttpClientModule,
    MatButtonModule,
    MatMenuModule,
    MatCardModule,
    MatToolbarModule,
    MatIconModule,
    MatSidenavModule,
    MatGridListModule,
    MatListModule
  ],
  exports: [
    SamplePackLibComponent,
    Db2Chart2Component,
    Db2Chart1Component
  ]
})
export class SamplePackLibModule { }

的package.json:

{
  "name": "sample-pack-lib",
  "version": "0.0.1",
  "dependencies": {    
  },
  "peerDependencies": {
    "@angular/common": "^7.2.0",
    "@angular/core": "^7.2.0",
    "@angular/material": "7.3.0"
  }
}

主要应用:

@Component({
  selector: 'app-admin',

  template: '<button (click)="load()">Load</button><ng-container #vc></ng-container>',
  styleUrls: ['./admin.component.scss']
})
export class AdminComponent {
  @ViewChild('vc', { read: ViewContainerRef }) vc: ViewContainerRef;

  private cfr: any;
  constructor(public compiler: Compiler, private injector: Injector, private r: ComponentFactoryResolver) { }

  load() {
    // register the modules that we already loaded so that no HTTP request is made
    // in my case, the modules are already available in my bundle (bundled by webpack)
    SystemJS.set('@angular/core', SystemJS.newModule(AngularCore));
    SystemJS.set('@angular/common', SystemJS.newModule(AngularCommon));
 SystemJS.set('@angular/material',SystemJS.newModule(AngularMaterial));
    SystemJS.set('@angular/router', SystemJS.newModule(AngularRouter));
    SystemJS.set('vis', SystemJS.newModule(Vis));
    SystemJS.set('@angular/common/http', SystemJS.newModule(HttpClientModule));

    const url = '../bundles/sample-pack-lib.umd.js';

    SystemJS.import(url).then((module) => {
   this.compiler.compileModuleAndAllComponentsAsync(module['SamplePackLibModule'])     
        .then((moduleFactory) => {
          const moduleRef = moduleFactory.ngModuleFactory.create(this.injector);
          const factory = moduleFactory.componentFactories.find(
            item => item.componentType.name === 'SamplePackLibComponent');

          if (factory) {
            const component = this.vc.createComponent(factory);
            const instance = component.instance;
          }
        });
    });
angular7 systemjs dynamic-loading umd
1个回答
0
投票

问题出在HttpCLientModule上。以前我以这种方式导入它:

import { HttpClientModule } from '@angular/common/http';

它应该是:

import * as HttpClientModule from '@angular/common/http';
© www.soinside.com 2019 - 2024. All rights reserved.