Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 作者列表
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
Menu

在 Angular 14 中向 NgModule 说不!

Posted on 2022-05-29

1098439.png

NgModules 将组件、指令和管道整合到有凝聚力的功能块中,每个功能块都专注于一个功能区域、应用程序业务域、工作流或实用程序的公共集合。

NgModule 是由 @NgModule 装饰器标记的类。 @NgModule 接受一个元数据对象,该对象描述如何编译组件的模板以及如何在运行时创建注入器。它通过exports 属性识别模块自己的组件、指令和管道,将其中一些公开,以便外部组件可以使用它们。 @NgModule 还可以将服务提供者添加到应用程序依赖注入器。

Angular 14 将引入另一种编写应用程序的方法——独立组件、指令和管道。

术语“独立”是指可以独立于 NgModule 使用的组件、指令或管道。尽管您仍然需要使用核心和外部 NgModule,但您可能不需要创建新的。

让我们创建一个没有 NgModules 的应用程序。首先,我们需要使用 angular-cli 生成它:

npx @angular/cli@next new ng14

下一步是删除 app.module.ts 并将 main.ts 中的 bootstrapModule() 函数替换为 bootstrapApplication():

 import { enableProdMode } from '@angular/core'; import { bootstrapApplication } from '@angular/platform-browser'; import { AppComponent } from './app/app.component'; import { environment } from './environments/environment'; if (environment.production) { enableProdMode(); } bootstrapApplication(AppComponent)

bootstrapApplication() 可以获取根组件及其所有子组件应该可用的提供程序列表:

 import { importProvidersFrom } from '@angular/core'; import { bootstrapApplication } from '@angular/platform-browser'; import { AppComponent } from './app/app.component'; import { HttpClientModule } from '@angular/common/http' bootstrapApplication(AppComponent, { providers: [importProvidersFrom(HttpClientModule)] }).catch(err => console.error(err));

该函数从提供的模块中提取提供者。

现在我们需要将 AppComponent 更改为独立组件。让我们将独立属性设置为true :

 @Component({ selector: 'app-root', templateUrl: './app.component.html', standalone: true, styleUrls: ['./app.component.scss'] }) export class AppComponent {}

现在我们可以在浏览器中看到 AppComponent 的模板。由于我们的组件是独立的,我们可以使用新的 imports 属性。 imports 属性指定组件的模板依赖项——它可以使用的那些指令、组件和管道。

独立组件可以导入其他独立组件、指令、管道和现有的 NgModules。例如,我们可以创建一个独立的指令,并在我们的组件中使用它:

 npx ng g directive foo --standalone
 import { Directive } from '@angular/core'; @Directive({ selector: '[appFoo]', standalone: true }) export class FooDirective {}
 import { CommonModule } from '@angular/common'; import { FooDirective } from './foo.directive'; @Component({ selector: 'app-root', template: ` <div appFoo *ngIf="bar">Foo</div> `, standalone: true, imports: [FooDirective, CommonModule] }) export class AppComponent {}

让我们向应用程序添加路由。

 const routes: Routes = [{ path: 'todos', component: TodosPageComponent }] @Component({ selector: 'app-root', template: ` <a routerLink="/todos">Todos</a> <router-outlet></router-outlet> `, standalone: true, imports: [RouterModule.forRoot(routes)], styleUrls: ['./app.component.scss'] }) export class AppComponent {}

这是不可能的,因为 Angular 不允许我们在独立组件中使用 ModuleWithProvider。接下来,我们可能会尝试在组件的提供程序中使用新的 importProvidersFrom 函数:

 const routes: Routes = [{ path: 'todos', component: TodosPageComponent }] @Component({ selector: 'app-root', template: ` <a routerLink="/todos">Todos</a> <router-outlet></router-outlet> `, standalone: true, providers: importProvidersFrom(RouterModule.forRoot(routes)), imports: [FooDirective, CommonModule], styleUrls: ['./app.component.scss'] }) export class AppComponent {}

使用应用内导航将起作用。路由器将错过第一次导航。路由器的初始化应该在引导过程中执行:

 bootstrapApplication(AppComponent, { providers: [importProvidersFrom(RouterModule.forRoot(routes))] }).catch(err => console.error(err));

TodosPageComponent 被急切地加载。让我们将其更改为延迟加载并添加一个 TodoPageComponent:

 import { Routes } from '@angular/router'; export const todosRoutes: Routes = [ { path: 'todos', title: 'Todos Page', children: [ { path: '', loadComponent: () => import('./todos-page.component').then((m) => m.TodosPageComponent), children: [ { path: ':id', loadComponent: () => import('./todo-page/todo-page.component').then( (m) => m.TodoPageComponent ), }, ], }, ], }, ];

我们不使用 loadChildren 并传递 NgModule,而是使用 loadComponent 属性并传递一个组件。我们还可以使用新的 providers 属性为这条 Route 及其子节点声明提供者:

 import { Routes } from '@angular/router'; export const todosRoutes: Routes = [ { path: 'todos', title: 'Todos Page', providers: [ { provide: 'Angular', useValue: 'v14', }, ], children: [ { path: '', loadComponent: () => import('./todos-page.component').then((m) => m.TodosPageComponent), children: [ { path: ':id', loadComponent: () => import('./todo-page/todo-page.component').then( (m) => m.TodoPageComponent ), }, ], }, ], }, ];

我们还可以将一组路由传递给 loadChildren:

 export const ROUTES: Route[] = [ { path: 'child', component: ChildCmp}, ]
 { path: 'parent', loadChildren: () => import('./children').then(m => m.ROUTES), }

结论:

未来几天,Angular 团队可能会推出 Angular 14 更新和新功能。敬请关注!

原文: https://dev.to/pranambhat/say-no-to-ngmodule-in-angular-14-39hl

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • Abhinav
  • Abigail Pain
  • Adam Fortuna
  • Alberto Gallego
  • Alex Wlchan
  • Answer.AI
  • Arne Bahlo
  • Ben Carlson
  • Ben Kuhn
  • Bert Hubert
  • Bits about Money
  • Brian Krebs
  • ByteByteGo
  • Chip Huyen
  • Chips and Cheese
  • Cool Infographics
  • Dan Sinker
  • David Walsh
  • Dmitry Dolzhenko
  • Elad Gil
  • Ellie Huxtable
  • Ethan Marcotte
  • Exponential View
  • FAIL Blog
  • Founder Weekly
  • Geoffrey Huntley
  • Geoffrey Litt
  • Greg Mankiw
  • Henrique Dias
  • Hypercritical
  • IEEE Spectrum
  • Investment Talk
  • Jaz
  • Jeff Geerling
  • Jonas Hietala
  • Josh Comeau
  • Lenny Rachitsky
  • Lou Plummer
  • Luke Wroblewski
  • Matt Stoller
  • Mert Bulan
  • Mostly metrics
  • News Letter
  • NextDraft
  • Non_Interactive
  • Not Boring
  • One Useful Thing
  • Phil Eaton
  • Product Market Fit
  • Readwise
  • ReedyBear
  • Robert Heaton
  • Ruben Schade
  • Sage Economics
  • Sam Altman
  • Sam Rose
  • selfh.st
  • Shtetl-Optimized
  • Simon schreibt
  • Slashdot
  • Small Good Things
  • Taylor Troesh
  • Telegram Blog
  • The Macro Compass
  • The Pomp Letter
  • thesephist
  • Thinking Deep & Wide
  • Tim Kellogg
  • 英文媒体
  • 英文推特
  • 英文独立博客
©2025 搞英语 → 看世界 | Design: Newspaperly WordPress Theme