angular / universal:没有DynamicFormValidationService的提供者

时间:2017-08-25 09:46:03

标签: angular dependency-injection angular-universal

我遇到的问题是,由于我切换到angular / universal并将AppModule拆分为ServerAppModuleBrowserAppMobile,因此未提供来自第三方模块的服务。

在这种情况下,我尝试包含@ng2-dynamic-forms包及其服务,但无论我如何安排导入,都不会提供服务DynamicFormValidationService

我已经尝试将DynamicFormsCoreModule.forRoot()导入直接放入AppSharedModule或两个AppModule类,但没有成功。

以下是我设置模块结构的方法,将CoreModuleSharedModule上的导入和服务分开。

ServerAppModule

@NgModule({
    bootstrap: [AppComponent],
    declarations: [AppComponent],
    imports: [
        ServerModule,
        // As explained here, animations module used document hence we need Noop animations module on server
        // https://github.com/angular/angular/issues/14784
        NoopAnimationsModule,
        AppModuleShared
    ]
})
export class AppModule { }

BrowserAppModule

@NgModule({
    bootstrap: [AppComponent],
    declarations: [AppComponent],
    imports: [
        AppModuleShared,
        BrowserAnimationsModule
    ],
    providers: [
        {
            provide: 'BASE_URL',
            useFactory: getBaseUrl
        }
    ]
})
export class AppModule {
}

SharedAppModule

@NgModule({
    imports: [
        BrowserModule,
        // our core modules
        CoreModule.forRoot(),
        SharedModule,
        // ngrx/store modules
        StoreModule.forRoot(appReducer),
        AppRoutingModule,
        StoreRouterConnectingModule,
        StoreDevtoolsModule.instrument({maxAge: 50})
    ],
    providers: [],
    exports: [
        SharedModule
    ],
    declarations: [
        HomeComponent
    ]
})
export class AppModuleShared {}

CoreModule

@NgModule({
    imports: [
        AuthModule.forRoot(),
        Ng2BootstrapModule.forRoot(),
        DynamicFormsCoreModule.forRoot()
    ],
    exports: [],
    providers: []
})
export class CoreModule {
    // forRoot allows to override providers
    // https://angular.io/docs/ts/latest/guide/ngmodule.html#!#core-for-root
    public static forRoot(): ModuleWithProviders {
        return {
            ngModule: CoreModule,
            providers: [
                Title,
                UtilityService
            ]
        };
    }
    constructor( @Optional() @SkipSelf() parentModule: CoreModule) {
        if (parentModule) {
            throw new Error('CoreModule is already loaded. Import it in the AppModule only');
        }
    }
}

SharedModule

@NgModule({
    imports: [
        CommonModule,
        FormsModule,
        ReactiveFormsModule,
        RouterModule,
        LayoutModule,
        Ng2BootstrapModule,
        DynamicFormsCoreModule,
        DynamicFormsBootstrapUIModule,
        // No need to export as these modules don't expose any components/directive etc'
        HttpModule,
        HttpClientModule
    ],
    declarations: [
    ],
    exports: [
        // Modules
        CommonModule,
        FormsModule,
        ReactiveFormsModule,
        RouterModule,
        LayoutModule,
        Ng2BootstrapModule,
        DynamicFormsCoreModule,
        DynamicFormsBootstrapUIModule
    ]

})
export class SharedModule {}

boot.browser.ts

if (module.hot) {
    module.hot.accept();
    module.hot.dispose(() => {
        modulePromise.then(appModule => appModule.destroy());
    });
} else {
    enableProdMode();
}

const modulePromise = platformBrowserDynamic().bootstrapModule(AppModule);

boot.server.ts

enableProdMode();

export default createServerRenderer(params => {
    const providers = [
        { provide: INITIAL_CONFIG, useValue: { document: '<appc-root></appc-root>', url: params.url } },
        { provide: APP_BASE_HREF, useValue: params.baseUrl },
        { provide: 'BASE_URL', useValue: params.origin + params.baseUrl },
    ];

    return platformDynamicServer(providers).bootstrapModule(AppModule).then(moduleRef => {
        const appRef: ApplicationRef = moduleRef.injector.get(ApplicationRef);
        const state = moduleRef.injector.get(PlatformState);
        const zone = moduleRef.injector.get(NgZone);

        return new Promise<RenderResult>((resolve, reject) => {
            zone.onError.subscribe((errorInfo: any) => reject(errorInfo));
            appRef.isStable.first(isStable => isStable).subscribe(() => {
                // Because 'onStable' fires before 'onError', we have to delay slightly before
                // completing the request in case there's an error to report
                setImmediate(() => {
                    resolve({
                        html: state.renderToString()
                    });
                    moduleRef.destroy();
                });
            });
        });
    });
});

1 个答案:

答案 0 :(得分:0)

这与我正在做的非常相似,我遇到了类似的问题。这就是我对你的代码修复它的原因:

<强> boot.browser.ts

const modulePromise = platformBrowserDynamic().bootstrapModule(BrowserAppModule);

<强> boot.server.ts

return platformDynamicServer(providers).bootstrapModule(ServerAppModule).then(...