В чем разница между объявлениями, поставщиками и импортом в NgModule?

Ответы:

518

Угловые понятия

  • imports делает экспортированные объявления других модулей доступными в текущем модуле
  • declarationsдолжны сделать директивы (включая компоненты и трубы) из текущего модуля доступными для других директив в текущем модуле. Селекторы директив, компонентов или каналов сопоставляются только с HTML, если они объявлены или импортированы.
  • providersдолжны сделать сервисы и значения известными DI (внедрение зависимости). Они добавляются в корневую область и внедряются в другие службы или директивы, которые имеют их в качестве зависимости.

Особый случай providers- лениво загруженные модули, которые получают собственный дочерний инжектор. providersмодуля с отложенной загрузкой по умолчанию предоставляются только этому загруженному модулю (но не всему приложению, как с другими модулями).

Для получения дополнительной информации о модулях см. Также https://angular.io/docs/ts/latest/guide/ngmodule.html.

  • exportsделает компоненты, директивы и каналы доступными в модулях, к которым добавляется этот модуль imports. exportsможет также использоваться для реэкспорта модулей, таких как CommonModule и FormsModule, что часто делается в общих модулях.

  • entryComponentsрегистрирует компоненты для автономной компиляции, чтобы их можно было использовать с ViewContainerRef.createComponent(). Компоненты, используемые в конфигурациях маршрутизатора, добавляются неявно.

Импорт TypeScript (ES2015)

import ... from 'foo/bar'(который может разрешить вindex.ts ) для импорта TypeScript. Они нужны вам всякий раз, когда вы используете идентификатор в файле машинописного текста, который объявлен в другом файле машинописного текста.

Angular @NgModule() importsи TypeScript import- это совершенно разные понятия .

См. Также jDriven - синтаксис импорта TypeScript и ES6

Большинство из них на самом деле представляют собой простой синтаксис модуля ECMAScript 2015 (ES6), который также используется в TypeScript.

Гюнтер Цохбауэр
источник
1
Я думаю, но я не уверен, что последняя рекомендация состоит в том, чтобы помещать провайдеров приложений в CoreModule, а не forRoot()в модуль с ленивой загрузкой. Ты согласен? Смотрите основной модуль . Ссылка на # shared-module-for-root больше не существует.
Марк Райкок
1
Отличное объяснение. Спасибо, @ günter-zöchbauer. importСледует упомянуть, что afaik - это функциональность JS (ES2015), а не TypeScript. :)
cassi.lup
и что такое экспорт [] в NgModule отстой, как экспорт: [MatCheckBox]
Омар Isaid
4
Честно говоря, я думаю, что дизайн NgModule of Angular неуклюж и неясен по сравнению с Vue и React . Вам нужно импортировать другой модуль с помощью imports, но экспортировать ваши деклараторы (компонент, директива, труба) с exports. Итак, основными целями importsи exportsявляются разные вещи. Вместо этого главная цель exports- ваша declarations. Вы объявляете свой компонент с помощью declarations, но для динамически загружаемого компонента вам необходимо вставить их entryComponents. Тем временем providersDI управляет другой историей.
xuemind
2
запутанный ответ, описывающий запутанные рамки
Донато
85

imports используются для импорта вспомогательных модулей, таких как FormsModule, RouterModule, CommonModule или любого другого пользовательского функционального модуля.

declarationsиспользуются для объявления компонентов, директив, каналов, которые принадлежат текущему модулю. Все внутри деклараций знают друг друга. Например, если у нас есть компонент, скажем UsernameComponent, который отображает список имен пользователей, и у нас также есть канал, скажем toupperPipe, который преобразует строку в строку заглавных букв. Теперь, если мы хотим отображать имена пользователей заглавными буквами в нашем компоненте UsernameComponent, тогда мы можем использовать созданную ранее toupperPipe, но вопрос в том, как UsernameComponent знает, что существует toupperPipe, и как он может получить к нему доступ и использовать его. Здесь идут объявления, мы можем объявить UsernameComponent и toupperPipe.

Providers используются для введения услуг, требуемых компонентами, директивами, трубами в модуле.

крестный отец
источник
3
«объявления: используется для объявления компонентов, директив, каналов, принадлежащих текущему модулю. Все внутри объявлений знают друг друга». это должен быть принятый ответ
Дин Джон
60

Компоненты объявлены, Модули импортированы, и Услуги предоставляются. Пример, с которым я работаю:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';


import { AppComponent } from './app.component';
import {FormsModule} from '@angular/forms';
import { UserComponent } from './components/user/user.component';
import { StateService } from './services/state.service';    

@NgModule({
  declarations: [
    AppComponent,
    UserComponent
  ],
  imports: [
    BrowserModule,
    FormsModule
  ],
  providers: [ StateService ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }
SanSolo
источник
3
Мне нравится простота этого объяснения, но меня удивляет, почему не существует только одного свойства "stuffsThisComponentNeeds"? Похоже, что все они имеют дело с одной и той же вещью, которая делает другие фрагменты кода доступными для текущего компонента.
redO.1013
1
@ redOctober13 Я согласен. Например, в Node.js все импортируется одинаково, независимо от того, является ли это моделью БД, модулем, службой или установленным сторонним пакетом. И я думаю, что то же самое происходит с реагировать JS
SanSolo
18

Угловые @NgModuleконструкции:

  1. import { x } from 'y';: Это стандартный синтаксис машинного текста ( ES2015/ES6модульный синтаксис) для импорта кода из других файлов. Это не специфично для Angular . Кроме того, это технически не является частью модуля, просто необходимо получить необходимый код в рамках этого файла.
  2. imports: [FormsModule]: Вы импортируете другие модули здесь. Например, мы импортируем FormsModuleв примере ниже. Теперь мы можем использовать функциональные возможности, которые FormsModule предлагает в этом модуле.
  3. declarations: [OnlineHeaderComponent, ReCaptcha2Directive]: Вы помещаете свои компоненты, директивы и трубы здесь. После объявления здесь вы можете использовать их во всем модуле. Например, теперь мы можем использовать OnlineHeaderComponentв AppComponentпредставлении (HTML-файл). Angular знает, где это найти, OnlineHeaderComponentпотому что он объявлен в @NgModule.
  4. providers: [RegisterService]: Здесь определяются наши сервисы этого конкретного модуля. Вы можете использовать службы в своих компонентах, внедрив их с помощью внедрения зависимостей.

Пример модуля:

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

// Components
import { AppComponent } from './app.component';
import { OfflineHeaderComponent } from './offline/offline-header/offline-header.component';
import { OnlineHeaderComponent } from './online/online-header/online-header.component';

// Services
import { RegisterService } from './services/register.service';

// Directives
import { ReCaptcha2Directive } from './directives/re-captcha2.directive';

@NgModule({
  declarations: [
    OfflineHeaderComponent,,
    OnlineHeaderComponent,
    ReCaptcha2Directive,
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
  ],
  providers: [
    RegisterService,
  ],
  entryComponents: [
    ChangePasswordComponent,
    TestamentComponent,
    FriendsListComponent,
    TravelConfirmComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
Виллем ван дер Веен
источник
10

Добавление быстрого шпаргалки, которая может помочь после долгого перерыва с Angular:


ЗАЯВЛЕНИЯ

Пример:

declarations: [AppComponent]

Что мы можем здесь ввести? Компоненты, трубы, директивы


ИМПОРТ

Пример:

imports: [BrowserModule, AppRoutingModule]

Что мы можем здесь ввести? другие модули


ПОСТАВЩИКИ

Пример:

providers: [UserService]

Что мы можем здесь ввести? Сервисы


начальная загрузка

Пример:

bootstrap: [AppComponent]

Что мы можем здесь ввести? основной компонент, который будет сгенерирован этим модулем (верхний родительский узел для дерева компонентов)


ВХОДНЫЕ КОМПОНЕНТЫ

Пример:

entryComponents: [PopupComponent]

Что мы можем здесь ввести? динамически генерируемые компоненты (например, с помощью ViewContainerRef.createComponent ())


ЭКСПОРТ

Пример:

export: [TextDirective, PopupComponent, BrowserModule]

Что мы можем здесь ввести? компоненты, директивы, модули или каналы, к которым мы хотели бы иметь доступ в другом модуле (после импорта этого модуля)

Przemek Struciński
источник
1
А как насчет экспорта?
lugte098
@ lugte098 Я добавил экспорт в этот список
Przemek Struciński
Я люблю этот макет для объяснения, очень удобоваримый. Спасибо!
Аарон Джордан
1
  1. объявления : Это свойство говорит о Компонентах, Директивах и Трубах, которые принадлежат этому модулю.
  2. экспорт : подмножество объявлений, которые должны быть видны и использоваться в шаблонах компонентов других NgModules.
  3. import : Другие модули, чьи экспортированные классы необходимы шаблонам компонентов, объявленным в этом NgModule.
  4. провайдеры : создатели услуг, которые этот NgModule вносит в глобальный набор услуг; они становятся доступными во всех частях приложения. (Вы также можете указать поставщиков на уровне компонентов, что часто является предпочтительным.)
  5. bootstrap : основное представление приложения, называемое корневым компонентом, в котором размещены все остальные представления приложения. Только корневой NgModule должен устанавливать свойство bootstrap.
Йогеш Вагмаре
источник