来自另一个模块的角度使用组件

问题描述 投票:171回答:7

我有使用angular-cli生成的Angular 2(2.0.0版-最终版)应用程序。

当我创建一个组件并将其添加到AppModule的声明数组时,一切都很好,它可以正常工作。

我决定分离组件,因此我创建了TaskModule和组件TaskCard。现在,我想在TaskCard的组件之一(AppModule组件)中使用Board

AppModule:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { BoardComponent } from './board/board.component';
import { LoginComponent } from './login/login.component';

import { MdButtonModule } from '@angular2-material/button';
import { MdInputModule } from '@angular2-material/input';
import { MdToolbarModule } from '@angular2-material/toolbar';

import { routing, appRoutingProviders} from './app.routing';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

import { UserService  } from './services/user/user.service';
import { TaskModule } from './task/task.module';


@NgModule({
  declarations: [
    AppComponent,
    BoardComponent,// I want to use TaskCard in this component
    LoginComponent,
    PageNotFoundComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    MdButtonModule,
    MdInputModule,
    MdToolbarModule,
    routing,
    TaskModule // TaskCard is in this module
  ],
  providers: [UserService],
  bootstrap: [AppComponent]
})
export class AppModule { }

TaskModule:

import { NgModule } from '@angular/core';
import { TaskCardComponent } from './task-card/task-card.component';

import { MdCardModule } from '@angular2-material/card';

@NgModule({
  declarations: [TaskCardComponent],
  imports: [MdCardModule],
  providers: []
})
export class TaskModule{}

整个项目在https://github.com/evgdim/angular2(看板文件夹)上可用

我想念的是什么?在TaskCardComponent中使用BoardComponent时需要做什么?

angular typescript angular-module
7个回答
341
投票

这里的主要规则是:

在组件模板的编译期间适用的选择器由声明该组件的模块以及该模块的导入的导出的传递闭包确定。

因此,请尝试将其导出:

@NgModule({
  declarations: [TaskCardComponent],
  imports: [MdCardModule],
  exports: [TaskCardComponent] <== this line
})
export class TaskModule{}

我应该出口什么?

导出应声明的类,其他模块中的组件应为能够在其模板中引用。这些是您的公开课。如果您不导出课程,则该课程将保持私有状态,仅对其他人可见该模块中声明的组件。

创建新模块的那一刻,无论是否懒惰,是否有任何新模块,然后在其中声明任何内容,该新模块都处于干净状态(如Ward Bell在https://devchat.tv/adv-in-angular/119-aia-avoiding-common-pitfalls-in-angular2中所说) >

Angular为每个@NgModule创建传递模块

”。

此模块收集从另一个模块导入的指令(如果导入的模块的可传递模块已导出指令)或在当前模块中声明的指令

当属于模块X的angular编译模板时,将使用在[[X.transitiveModule.directives

中收集的那些指令。compiledTemplate = new CompiledTemplate( false, compMeta.type, compMeta, ngModule, ngModule.transitiveModule.directives);
https://github.com/angular/angular/blob/4.2.x/packages/compiler/src/jit/compiler.ts#L250-L251

enter image description here

根据上图的这种方式

  • YComponent不能在其模板中使用ZComponent,因为directivesTransitive module Y数组不包含ZComponent,因为YModule尚未导入其传递模块包含ZModuleZComponentexportedDirectives数组中。

  • XComponent模板内,我们可以使用ZComponent,因为Transitive module X具有包含ZComponent的指令数组,因为XModule导入模块(YModule),导出模块(ZModule)导出指令ZComponent
  • AppComponent模板中,我们无法使用XComponent,因为AppModule会导入XModule,但XModule不会导出XComponent
  • 另请参见

] >>
  • [Angular Module FAQs

  • ] >>
  • What is difference between declarations, providers and import in NgModule
  • 您必须从export中将其NgModule

    @NgModule({ declarations: [TaskCardComponent], exports: [TaskCardComponent], imports: [MdCardModule], providers: [] }) export class TaskModule{}

    ((角度2-角度7)] >>

    组件只能在单个模块中声明。为了使用另一个模块中的组件,您需要执行两个简单的任务:

      导出另一个模块中的组件
  • 将另一个模块导入当前模块
  • 第一个模块:

  • [拥有一个组件(我们称它为“ ImportantCopmonent”),我们想在第二个模块的页面中重复使用。

    @NgModule({ declarations: [ FirstPage, ImportantCopmonent // <-- Enable using the component html tag in current module ], imports: [ IonicPageModule.forChild(NotImportantPage), TranslateModule.forChild(), ], exports: [ FirstPage, ImportantCopmonent // <--- Enable using the component in other modules ] }) export class FirstPageModule { }


    第二模块:

    通过导入FirstPageModule,重用“ ImportantCopmonent”

    @NgModule({ declarations: [ SecondPage, Example2ndComponent, Example3rdComponent ], imports: [ IonicPageModule.forChild(SecondPage), TranslateModule.forChild(), FirstPageModule // <--- this Imports the source module, with its exports ], exports: [ SecondPage, ] }) export class SecondPageModule { }

    注意,为了创建所谓的“功能模块”,您需要在其中导入CommonModule。因此,您的模块初始化代码将如下所示:

    import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { TaskCardComponent } from './task-card/task-card.component'; import { MdCardModule } from '@angular2-material/card'; @NgModule({ imports: [ CommonModule, MdCardModule ], declarations: [ TaskCardComponent ], exports: [ TaskCardComponent ] }) export class TaskModule { }

    此处提供更多信息:https://angular.io/guide/ngmodule#create-the-feature-module

    无论您想在其他模块中使用什么,只需将其放在

    export array中即可。像这样-

    @NgModule({ declarations: [TaskCardComponent], exports: [TaskCardComponent], imports: [MdCardModule] })

    解决了如何使用其他模块的模块中声明的组件。

    基于Royi Namir的解释(非常感谢。)在使用延迟加载时,缺少在其他模块中重用模块中声明的组件的部分。

    第一:将组件导出到包含它的模块中:

    @NgModule({ declarations: [TaskCardComponent], imports: [MdCardModule], exports: [TaskCardComponent] <== this line }) export class TaskModule{}

    第二:在要使用TaskCardComponent的模块中:

    import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { MdCardModule } from '@angular2-material/card'; @NgModule({ imports: [ CommonModule, MdCardModule ], providers: [], exports:[ MdCardModule ] <== this line }) export class TaskModule{}

    类似第二个模块导入第一个导入和导出组件的模块。

    当我们在第二个模块中导入模块时,我们需要再次导出它。现在,我们可以在第二个模块中使用第一个组件。

    一种很棒的方法是从NgModuleFactory加载模块,您可以通过调用此模块在另一个模块内加载模块:

    constructor(private loader: NgModuleFactoryLoader, private injector: Injector) {} loadModule(path: string) { this.loader.load(path).then((moduleFactory: NgModuleFactory<any>) => { const entryComponent = (<any>moduleFactory.moduleType).entry; const moduleRef = moduleFactory.create(this.injector); const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent); this.lazyOutlet.createComponent(compFactory); }); }

    我是从here获得的。

    36
    投票
    您必须从export中将其NgModule

    @NgModule({ declarations: [TaskCardComponent], exports: [TaskCardComponent], imports: [MdCardModule], providers: [] }) export class TaskModule{}


    23
    投票
    ((角度2-角度7)] >>

    组件只能在单个模块中声明。为了使用另一个模块中的组件,您需要执行两个简单的任务:

      导出另一个模块中的组件

    2
    投票
    注意,为了创建所谓的“功能模块”,您需要在其中导入CommonModule。因此,您的模块初始化代码将如下所示:

    import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { TaskCardComponent } from './task-card/task-card.component'; import { MdCardModule } from '@angular2-material/card'; @NgModule({ imports: [ CommonModule, MdCardModule ], declarations: [ TaskCardComponent ], exports: [ TaskCardComponent ] }) export class TaskModule { }

    此处提供更多信息:https://angular.io/guide/ngmodule#create-the-feature-module

    0
    投票
    无论您想在其他模块中使用什么,只需将其放在

    export array中即可。像这样-

    @NgModule({ declarations: [TaskCardComponent], exports: [TaskCardComponent], imports: [MdCardModule] })

    0
    投票

    解决了如何使用其他模块的模块中声明的组件。

    基于Royi Namir的解释(非常感谢。)在使用延迟加载时,缺少在其他模块中重用模块中声明的组件的部分。

    0
    投票
    一种很棒的方法是从NgModuleFactory加载模块,您可以通过调用此模块在另一个模块内加载模块:

    constructor(private loader: NgModuleFactoryLoader, private injector: Injector) {} loadModule(path: string) { this.loader.load(path).then((moduleFactory: NgModuleFactory<any>) => { const entryComponent = (<any>moduleFactory.moduleType).entry; const moduleRef = moduleFactory.create(this.injector); const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent); this.lazyOutlet.createComponent(compFactory); }); }

    我是从here获得的。
    © www.soinside.com 2019 - 2024. All rights reserved.