getDOM()为null - 从Angular 2迁移到Angular 4

时间:2017-06-17 16:33:13

标签: angular

我面临一个我无法解决的特殊问题。我找到了similar problems,但它的解决方案并不适用于我。

我正在将一个项目从Angular 2移动到Angular 4.我开始从头开始创建一个ng项目,使用最新的angular-cli,安装所需的模块并复制/粘贴我的旧项目结构。

这是来自app.module.ts的代码:

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    LoginComponent,
    SignupComponent,
    ForgotComponent,
    SelectBoxToDownloadFromGeoserverDialog,
    ValidateTokenComponent,
    ChangePasswordTokenComponent,
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    FormsModule,
    HttpModule,
    ReCaptchaModule,
    LoadingAnimateModule.forRoot(),
    //MaterialModule,
    RouterModule.forRoot(appRoutes, { useHash: true }),
    MaterialModule
  ],
  entryComponents : [LoginComponent, SignupComponent, ForgotComponent, SelectBoxToDownloadFromGeoserverDialog],
  providers: [
    LoadingAnimateService,
    AuthService,
    CanActivateAdmin,
    {
      provide: HighchartsStatic,
      useFactory: highchartsFactory
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

成功编译后,我在浏览器中收到此(奇怪的)错误:

Unhandled Promise rejection: getDOM(...) is null ; Zone: <root> ; Task: Promise.then ; Value: TypeError: getDOM(...) is null
Traza de la pila:
_createNgProbe@http://localhost:3000/vendor.bundle.js:94380:6
anonymous/AppModuleNgFactory</<@ng:///AppModule/module.ngfactory.js:119:58
_callFactory@http://localhost:3000/vendor.bundle.js:10123:26
_createProviderInstance$1@http://localhost:3000/vendor.bundle.js:10052:26
initNgModule@http://localhost:3000/vendor.bundle.js:10003:13
NgModuleRef_@http://localhost:3000/vendor.bundle.js:11111:9
createNgModuleRef@http://localhost:3000/vendor.bundle.js:11095:12
debugCreateNgModuleRef@http://localhost:3000/vendor.bundle.js:13379:12
NgModuleFactory_.prototype.create@http://localhost:3000/vendor.bundle.js:14374:16
PlatformRef_.prototype._bootstrapModuleFactoryWithZone/<@http://localhost:3000/vendor.bundle.js:5032:47
ZoneDelegate.prototype.invoke@http://localhost:3000/polyfills.bundle.js:2758:17
onInvoke@http://localhost:3000/vendor.bundle.js:4409:28
ZoneDelegate.prototype.invoke@http://localhost:3000/polyfills.bundle.js:2757:17
Zone.prototype.run@http://localhost:3000/polyfills.bundle.js:2508:24
NgZone.prototype.run@http://localhost:3000/vendor.bundle.js:4277:51
PlatformRef_.prototype._bootstrapModuleFactoryWithZone@http://localhost:3000/vendor.bundle.js:5030:16
PlatformRef_.prototype._bootstrapModuleWithZone/<@http://localhost:3000/vendor.bundle.js:5072:53
ZoneDelegate.prototype.invoke@http://localhost:3000/polyfills.bundle.js:2758:17
Zone.prototype.run@http://localhost:3000/polyfills.bundle.js:2508:24
scheduleResolveOrReject/<@http://localhost:3000/polyfills.bundle.js:3185:52
ZoneDelegate.prototype.invokeTask@http://localhost:3000/polyfills.bundle.js:2791:17
Zone.prototype.runTask@http://localhost:3000/polyfills.bundle.js:2558:28
drainMicroTaskQueue@http://localhost:3000/polyfills.bundle.js:2951:25
 _createNgProbe@http://localhost:3000/vendor.bundle.js:94380:6
anonymous/AppModuleNgFactory</<@ng:///AppModule/module.ngfactory.js:119:58
_callFactory@http://localhost:3000/vendor.bundle.js:10123:26
_createProviderInstance$1@http://localhost:3000/vendor.bundle.js:10052:26
initNgModule@http://localhost:3000/vendor.bundle.js:10003:13
NgModuleRef_@http://localhost:3000/vendor.bundle.js:11111:9
createNgModuleRef@http://localhost:3000/vendor.bundle.js:11095:12
debugCreateNgModuleRef@http://localhost:3000/vendor.bundle.js:13379:12
NgModuleFactory_.prototype.create@http://localhost:3000/vendor.bundle.js:14374:16
PlatformRef_.prototype._bootstrapModuleFactoryWithZone/<@http://localhost:3000/vendor.bundle.js:5032:47
ZoneDelegate.prototype.invoke@http://localhost:3000/polyfills.bundle.js:2758:17
onInvoke@http://localhost:3000/vendor.bundle.js:4409:28
ZoneDelegate.prototype.invoke@http://localhost:3000/polyfills.bundle.js:2757:17
Zone.prototype.run@http://localhost:3000/polyfills.bundle.js:2508:24
NgZone.prototype.run@http://localhost:3000/vendor.bundle.js:4277:51
PlatformRef_.prototype._bootstrapModuleFactoryWithZone@http://localhost:3000/vendor.bundle.js:5030:16
PlatformRef_.prototype._bootstrapModuleWithZone/<@http://localhost:3000/vendor.bundle.js:5072:53
ZoneDelegate.prototype.invoke@http://localhost:3000/polyfills.bundle.js:2758:17
Zone.prototype.run@http://localhost:3000/polyfills.bundle.js:2508:24
scheduleResolveOrReject/<@http://localhost:3000/polyfills.bundle.js:3185:52
ZoneDelegate.prototype.invokeTask@http://localhost:3000/polyfills.bundle.js:2791:17
Zone.prototype.runTask@http://localhost:3000/polyfills.bundle.js:2558:28
drainMicroTaskQueue@http://localhost:3000/polyfills.bundle.js:2951:25

也许有帮助,这是我的package.json

{
  "name": "test1",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^4.0.0",
    "@angular/common": "^4.0.0",
    "@angular/compiler": "^4.0.0",
    "@angular/core": "^4.0.0",
    "@angular/forms": "^4.0.0",
    "@angular/http": "^4.0.0",
    "@angular/material": "^2.0.0-beta.6",
    "@angular/platform-browser": "^4.0.0",
    "@angular/platform-browser-dynamic": "^4.0.0",
    "@angular/router": "^4.0.0",
    "angular-pipes": "^6.5.2",
    "angular2-highcharts": "^0.5.5",
    "angular2-recaptcha": "^0.6.0",
    "core-js": "^2.4.1",
    "hammerjs": "^2.0.8",
    "jquery": "^3.2.1",
    "ng2-ckeditor": "^1.1.8",
    "ng2-dragula": "^1.5.0",
    "ng2-loading-animate": "0.0.17",
    "ng2-md-datatable": "^1.4.0",
    "ng2-truncate": "^1.3.7",
    "openlayers": "^4.2.0",
    "proj4": "^2.4.3",
    "rxjs": "^5.1.0",
    "zone.js": "^0.8.4"
  },
  "devDependencies": {
    "@angular/cli": "1.0.6",
    "@angular/compiler-cli": "^4.0.0",
    "@types/jasmine": "2.5.38",
    "@types/node": "~6.0.60",
    "codelyzer": "~2.0.0",
    "jasmine-core": "~2.5.2",
    "jasmine-spec-reporter": "~3.2.0",
    "karma": "~1.4.1",
    "karma-chrome-launcher": "~2.1.1",
    "karma-cli": "~1.0.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "karma-coverage-istanbul-reporter": "^0.2.0",
    "protractor": "~5.1.0",
    "ts-node": "~2.0.0",
    "tslint": "~4.5.0",
    "typescript": "~2.2.0"
  }
}

如何解决此错误及其产生的原因?

1 个答案:

答案 0 :(得分:3)

我对此问题进行了调查,发现它与ng2-loading-animate有关。

我感到很惊讶,因为这个repo在其包中发布了角度源代码。更准确地说,它包括角度BrowserAnimationModuleBrowserModule v4.1.3。

此代码中的ng2-loading-animate

出错
function _createNgProbe(extraTokens, coreTokens) {
    var /** @type {?} */ tokens = (extraTokens || []).concat(coreTokens || []);
    getDOM().setGlobalVar(INSPECT_GLOBAL_NAME, inspectNativeElement);
    getDOM().setGlobalVar(CORE_TOKENS_GLOBAL_NAME, __assign({}, CORE_TOKENS, _ngProbeTokensToMap(tokens || [])));
    return function () { return inspectNativeElement; };
}

来自

<强> NG2加载-animate.js

var ELEMENT_PROBE_PROVIDERS = [
    {
        provide: _angular_core.APP_INITIALIZER,
        useFactory: _createNgProbe, // this line
        deps: [
            [NgProbeToken$1, new _angular_core.Optional()],
            [_angular_core.NgProbeToken, new _angular_core.Optional()],
        ],
        multi: true,
    },
];

<强> NG2加载-animate.js

            ||
            \/

BrowserModule.decorators = [
    { type: _angular_core.NgModule, args: [{
                providers: [
                    BROWSER_SANITIZATION_PROVIDERS,
                    { provide: _angular_core.ErrorHandler, useFactory: errorHandler, deps: [] },
                    { provide: EVENT_MANAGER_PLUGINS, useClass: DomEventsPlugin, multi: true },
                    { provide: EVENT_MANAGER_PLUGINS, useClass: KeyEventsPlugin, multi: true },
                    { provide: EVENT_MANAGER_PLUGINS, useClass: HammerGesturesPlugin, multi: true },
                    { provide: HAMMER_GESTURE_CONFIG, useClass: HammerGestureConfig },
                    DomRendererFactory2,
                    { provide: _angular_core.RendererFactory2, useExisting: DomRendererFactory2 },
                    { provide: SharedStylesHost, useExisting: DomSharedStylesHost },
                    DomSharedStylesHost,
                    _angular_core.Testability,
                    EventManager,
                    ELEMENT_PROBE_PROVIDERS, // this line
                    Meta,
                    Title,
                ],
                exports: [_angular_common.CommonModule, _angular_core.ApplicationModule]
            },] },
];

<强> NG2加载-animate.js

           ||
           \/

BrowserAnimationsModule.decorators = [
    { type: _angular_core.NgModule, args: [{
                imports: [_angular_platformBrowser.BrowserModule],
                providers: BROWSER_ANIMATIONS_PROVIDERS,
            },] },
];

<强> NG2加载-animate.js

           ||
           \/

LoadingAnimateModule = LoadingAnimateModule_1 = __decorate([
    core_1.NgModule({
        declarations: [
            ng2_loading_animate_component_1.LoadingAnimateComponent
        ],
        imports: [common_1.CommonModule, animations_1.BrowserAnimationsModule],
        exports: [ng2_loading_animate_component_1.LoadingAnimateComponent],
        providers: [ng2_loading_animate_service_1.LoadingAnimateService]
    })
], LoadingAnimateModule);

<强> app.module.ts

           ||
           \/

imports: [
  LoadingAnimateModule.forRoot(),

因此,当您导入LoadingAnimateModule模块时,会读取其元数据并将_createNgProbe工厂添加到APP_INITIALIZER多提供程序。当您的应用程序启动时,角度执行此工厂后,从原始@angular/platform-browser代码执行相同的工厂。

<强> module.ngfactory.js

jit_InjectionToken_Application_Initializer68,function(p0_0,p0_1,p1_0, p1_1) {
    return [jit__createNgProbe69(p0_0,p0_1),jit__createNgProbe70(p1_0, p1_1)];
                    /\                             /\
                    ||                             ||
           angular/platform-browser          ng2-loading-animate

来自_createNgProbe的{​​{1}}方法与当前版本的角度

不匹配

<强> @角/平台的浏览器

ng2-loading-animate

您可以使用以下代码解决此问题

function _createNgProbe(extraTokens, coreTokens) {
    var /** @type {?} */ tokens = (extraTokens || []).concat(coreTokens || []);
    exportNgVar(INSPECT_GLOBAL_NAME, inspectNativeElement);
    exportNgVar(CORE_TOKENS_GLOBAL_NAME, Object.assign({}, CORE_TOKENS, _ngProbeTokensToMap(tokens || [])));
    return function () { return inspectNativeElement; };
}

但是我建议你在import { CommonModule } from '@angular/common'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; let metadata = Reflect.getOwnMetadata('annotations', LoadingAnimateModule); metadata[0].imports = [CommonModule, BrowserAnimationsModule]; repo中编写bug报告,因为角度库不应该包含角度代码。