【问题标题】:Angular 2: misunderstanding with importsAngular 2:对导入的误解
【发布时间】:2017-05-02 00:23:00
【问题描述】:

我想从 angular 1.4 移植一些结构...

我有一些麻烦。例如我有这样的结构:

components - 是一个模块,customer 是一个模块,list - 是一个模块。

我在导入模块和组件时遇到问题。

我是这样做的:

app.module

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 { MaterialModule } from '@angular/material';
import 'hammerjs';

import {NgbModule} from '@ng-bootstrap/ng-bootstrap';

import { ComponentsModule } from './components/components.module';
import { CoreModule } from './core/core.module';
import { ServicesModule } from './services/services.module';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    MaterialModule.forRoot(),
    ComponentsModule,
    CoreModule,
    ServicesModule,
    NgbModule.forRoot()
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.html

<customer-list></customer-list>

如果我在这里使用 angular2 引导程序:

<ngb-accordion #acc="ngbAccordion" activeIds="ngb-panel-0">
  <ngb-panel title="Simple">
    <template ngbPanelContent>
      demo
    </template>
  </ngb-panel>
</ngb-accordion>

一切正常。

components.module

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

import { CustomerModule } from './customer/customer.module';

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [],
  exports: [CustomerModule]
})
export class ComponentsModule { }

customer.module

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { CustomerComponent } from './customer.component';
import { ListComponent } from './list/list.component';
import { ItemComponent } from './list/item/item.component';

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [CustomerComponent, ListComponent, ItemComponent],
  exports: [CustomerComponent, ListComponent]
})
export class CustomerModule { }

list.module

import { NgModule } from '@angular/core';

import {NgbModule} from '@ng-bootstrap/ng-bootstrap';

import { CommonModule } from '@angular/common';
import { ListComponent } from './list.component';
import { ItemComponent } from './item/item.component';

@NgModule({
  imports: [
    CommonModule,
    NgbModule
  ],
  declarations: [ListComponent, ItemComponent],
  exports: [ListComponent]
})
export class CustomerModule { }

list.component.html

  <ngb-accordion #acc="ngbAccordion">
    <ngb-panel >
      <template ngbPanelContent>
        test
      </template>
    </ngb-panel>
  </ngb-accordion>

在这里我得到错误:

zone.js:388Unhandled Promise 拒绝:模板解析错误: 'ngb-panel' 不是已知元素:

但是如果我在每个模块中导入NgbModule,直到我到达 app.module - 一切都很好。但这太荒谬了。

有没有可能以 Angular 2 组织模块的导入,所以,一旦在根目录中导入,我就不需要在每个模块中导入它们 - 我可以在嵌套模块中重用它们,就像在 Angular 中一样1.4(使用 ngInject)?

【问题讨论】:

  • 如果您只在ListModule 中使用NgbModule,那么您只需将其导入那里。你说得对 :) 可能有点远,但是&lt;ngb-panel &gt; 中的额外空间会不会是问题所在?
  • @PierreDuc 似乎没有帮助(

标签: angular typescript


【解决方案1】:

要在ListModule 中使用NgbModule,您应该像以前一样将它添加到导入数组中。但您也应该将其导入您的AppModule。所以只有两个地方。您使用它的模块,以及根模块中的 forRoot() 导入,该模块还导入了 BrowserModule

仅相关代码:AppModule

@NgModule({
...
  imports: [
    BrowserModule,
    NgbModule.forRoot()
  ]
...
})
export class AppModule {}

仅相关代码:ListModule

@NgModule({
  imports: [
    CommonModule,
    NgbModule
  ],
  declarations : [
    ListComponent,
    ItemComponent
  ],
  exports : [
    ListComponent,
    ItemComponent
  ]
})
export class ListModule{}
//you named this CustomerModule for some reason....
//could also be the problem, or just a wrong copy paste :)

如果您想在您的CustomerModule 中使用ListComponent,您应该导入ListModule 而不是ListComponent

@NgModule({
  imports: [
    CommonModule,
    ListModule
  ],
  declarations: [CustomerComponent],
  exports: [CustomerComponent]
})
export class CustomerModule {}

如果您只导入ListComponent,它将看不到您在ListModule 中导入的NgbModule。经验法则,仅导入/声明属于该模块的组件。不要从其他模块导入/声明组件/指令/管道/服务。只导入整个模块。但是,您可以在另一个模块中导出一个模块。这样,如果您导入导出另一个模块的模块,则另一个模块也可用。 (这没有多大意义)。让我给你写下来:

组件模块只导出客户模块

@NgModule({
   exports : [
      CustomerModule
   ]
})
export class ComponentsModule{}

客户模块导入导出列表模块

@NgModule({
   imports : [
     ListModule
   ],
   exports : [
     ListModule
   ]
})
export class CustomerModule{}

列表模块导出列表组件

@NgModule({
   imports : [
     NgbModule
   ],
   declarations: [
     ListComponent
   ],
   exports : [
     ListComponent
   ]
})
export class ListModule{}

应用模块导入组件模块

@NgModule({
   imports : [
     BrowserModule,
     NgbModule.forRoot()
     ComponentsModule
   ]
})
export class AppModule{}

据我所知,您现在可以在您的AppModule 中使用ListComponent。因为客户模块也导出ListModule。我认为这有点违反直觉,建议只在客户模块中导入列表模块,在组件模块中导出列表模块。

【讨论】:

  • 为什么要在 CustomerModule 中声明 ListComponent?如果你想使用 ListComponent,你应该在你的 CustomerModule 中导入 ListModule。我相信这就是你的问题所在。我已经更新了答案
  • good) 为什么我要使用嵌套:对于 Angular 1.4 中的我来说,拥有例如组件/卡片/列表/项目要容易得多且明显得多,它们都不会在一个层次上分开......
  • 你会如何组织这样的结构?例如,我有客户屏幕,带有客户列表或客户详细信息(具有一些共享样式,例如面板),列表和客户有自己的路线路径。我的架构是否适合这个?
  • 客户将是一个包含客户列表和客户详细信息的模块。您的组件模块将导出组件以创建一个列表,甚至可能是一个详细信息屏幕。您的客户模块导入此组件模块以构建详细信息和列表屏幕。您的 appmodule 导入客户模块。但这仅适用于您的组件模块的行为类似于公共模块的情况,否则我现在看到用于组件模块
【解决方案2】:

请参阅另一个线程中的this 答案,因此在 Angular 2 中似乎不可能,因为每个组件都是模块化的,需要自己导入,否则模块化将会丢失。

你可以有详细的使用说明here as well.

【讨论】:

  • 是的,好的,每个模块都在导入依赖项。但是为什么如果我在列表模块中使用 ngbModule,我需要在客户、组件等中导入它?
  • 你需要在你使用的每个模块中导入它,因为没有像“父”模块之类的东西,每个模块都有自己的依赖项,因此需要自己的导入。
  • 检查我的问题...这是真的吗,即使我没有在应用程序视图中使用它,我也需要在任何地方(组件、客户)导入 ngbModule?我在应用视图中只使用列表模块
【解决方案3】:

Angular2 中的模块背后的想法是它是一个独立的可重用 模块。然而,这确实意味着无论模块需要什么,必须由模块本身导入。

如果导入的模块是继承的,则这些模块不再是独立的,因此不再可重用,您将失去模块化系统的大部分优势。

【讨论】:

  • 是的,好的,每个模块都在导入依赖项。但是为什么如果我在列表模块中使用 ngbModule,我需要在客户、组件等中导入它?
  • 你应该只需要将它导入到任何声明组件、管道、指令等的模块中,这些模块使用来自导入模块的东西。
  • 检查我的问题...这是真的吗,即使我没有在应用程序视图中使用它,我也需要在任何地方(组件、客户)导入 ngbModule?我在应用视图中只使用列表模块
  • 您只在定义使用它的组件的实际模块中导入它。在您的示例中,您在list.component.html 中使用它。目前尚不清楚该模板属于哪个 Component,也不清楚该组件在哪个 Module 中定义。但假设该模板由 ListModule 中定义的 ListComponent 使用,那么您只需将 ngbModule 添加到ListModule
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-24
  • 2017-09-02
  • 2016-10-29
  • 1970-01-01
  • 2017-04-04
  • 2018-01-08
相关资源
最近更新 更多