如何通过Angular2中的sharedModule在多个位置使用组件

时间:2017-01-28 07:46:38

标签: angular

经验丰富的Angular 1家伙,但是在本周末转到Angular 2时,我无法得到一个概念。花了一天时间,结束了圈子,所以也许有人可以提供帮助。

我试图将ui组件包含在多个路由中(模块?)。从我一直阅读的内容来看,最简洁的方法是创建一个共享模块,将我想要的组件导出到多个其他组件。

考虑到这一点,我直接从angular-cli创建了一个剥离后的项目,试图将MainNavComponent引入AppModule,以及一个单独的路径模块(About)。

它在主应用程序组件html中按预期显示,但如果尝试将其包含在about组件html中,则抛出以下错误:

Unhandled Promise rejection: Template parse errors:
'app-main-nav' is not a known element:
1. If 'app-main-nav' is an Angular component, then verify that it is part of this module.
2. If 'app-main-nav' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message. ("[ERROR ->]<app-main-nav></app-main-nav>

我意识到不需要在应用程序和about路线中包含主导航,只是为了示例目的。

我不了解共享模块的功能,还是我的实现错了?

难以编写整个代码结构,因此我将一个测试床项目作为公共GitHub仓库,您可以看到它是如何构建的。

https://github.com/IamAdamJowett/angular-2-test-bed

如果在上面的代表处执行ng serve并转到http://localhost:4200/about,您可以看到错误。非常感谢。

2 个答案:

答案 0 :(得分:0)

在完成了几个Angular2项目后,我已经针对SharedModuleAppModule采用了以下格式,并且它始终适用于我。

在所有其他模块中,只需导入SharedModule

即可

<强> SharedModule

import { NgModule, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common';

// **import all angular modules that will be shared**
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MaterialModule } from '@angular/material';
import { FlexLayoutModule } from '@angular/flex-layout';

// **import all shared third-party modules**
import { TranslateModule } from 'ng2-translate/ng2-translate';
import { ResponsiveModule } from 'ng2-responsive';

// **import all shared services of your app**
import { MyServiceA, MyServiceB, MyServiceC } from './services';

// **import all shared components, directives & pipes of your app**
import { MyComponentA, MyComponentB, MyComponentC } from './components';
import { MyDirectiveA, MyDirectiveB, MyDirectiveC } from './directives';
import { MyPipeA, MyPipeB } from '../pipes';

// **import any other shared sub-module**
import { MyOtherSharedSubModule } from './shared-sub.module';

@NgModule({
    imports: [
        // import all modules to share
        CommonModule,
        FormsModule,
        ReactiveFormsModule,
        MaterialModule,
        FlexLayoutModule,
        TranslateModule,
        ResponsiveModule,
        MyOtherSharedSubModule
    ],
    declarations: [
        // Declare all shared components/pipes/directives
        MyComponentA,
        MyComponentB,
        MyComponentC,
        MyDirectiveA,
        MyDirectiveB,
        MyDirectiveC,
        MyPipeA,
        MyPipeB
    ],
    exports: [
        // export all shared modules/components/pipes/dirctives
        FormsModule,
        ReactiveFormsModule,
        MaterialModule,
        FlexLayoutModule,
        TranslateModule,
        ResponsiveModule,
        MyOtherSharedSubModule,
        MyComponentA,
        MyComponentB,
        MyComponentC,
        MyDirectiveA,
        MyDirectiveB,
        MyDirectiveC,
        MyPipeA,
        MyPipeB
    ]
})
export class SharedModule {

    static forRoot(): ModuleWithProviders {
        return {
            ngModule: SharedModule,
            providers: [
                // Add all shared services
                MyServiceA,
                MyServiceB,
                MyServiceC
            ]
        };
    }
}

<强>的AppModule

// ** import all angular modules**
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, APP_INITIALIZER } from '@angular/core';
import { HttpModule, Http } from '@angular/http';

// **import other modules that require .forRoot()**
import { MaterialModule } from '@angular/material';
import { FlexLayoutModule } from '@angular/flex-layout';

// **import third-party modules that require .forRoot()**
import { TranslateModule, TranslateLoader, TranslateStaticLoader } from 'ng2-translate/ng2-translate';

// **import AppComponent, AppRoutesModule etc**
import { AppComponent } from './app.component';
import { AppRoutesModule } from './app-routes.module';

// **import SharedModules
import { SharedModule } from './shared';

// **import other root-level components
import { LoginComponent, ForgotPasswordComponent } from './components';

// **create loader/config factories for third party modules if required
export function translateLoaderFactory(http: Http) {
    return new TranslateStaticLoader(http, './assets/i18n', '.json');
}

export function translateLoader(): any {
    return {
        provide: TranslateLoader,
        useFactory: translateLoaderFactory,
        deps: [Http]
    };
}

@NgModule({
    declarations: [
        // **declare only root level components here
        AppComponent,
        LoginComponent,
        ForgotPasswordComponent
    ],
    imports: [
        BrowserModule, // <=== Must import
        HttpModule,    // <=== Must import

        // **import other modules that require .forRoot()**
        MaterialModule.forRoot(),
        FlexLayoutModule.forRoot(),
        TranslateModule.forRoot(translateLoader()),

        // **import the SharedModule**
        SharedModule.forRoot(),

        // **import AppRoutesModule**
        AppRoutesModule
    ],
    providers: [
        // **specify root level services (if any)**
        // **specify service for APP_INITIALIZER (if any)**
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

答案 1 :(得分:0)

所以最后的解决方案是,因为我使用的是专用路由模块,所以我需要将SharedModule引入该路由模块,以便路由可以使用它(将它带入AppModule是不够的)。感谢@yurzui让我走上了正确的道路。

我已经更新了测试回购,以防万一有人好奇或在使用带角度cli的路由后出现同样的问题。