2018 年 9 月

33 卷,第 9

此文章由机器翻译

孜孜不倦的程序员 - 怎样算是严苛:路由 Angular

通过Ted Neward |2018 年 9 月

Ted Neward我们又见面了,MEAN 用户们。

到目前为止,尽管我们已安装了工具,所有一切实质上是完成了完全在作用域的一个"页。" 虽然这会使某些单页面应用程序 (Spa) Web 应用的用户的意义上甚至是最复杂的 Web 应用 (或最复杂的用户) 通常遵循的一些已建立的,类似于 Web 的可访问性通过 URL 原则。也就是说,我应该能够"跳转"到应用程序的某些部分只需输入到浏览器中,相应的 URL 或某个页面加入书签,在这个问题上,依次类推。"内部"应用程序导航的能力的特点,在桌面或移动应用中,只要 Web 应用,它是应支持一项重要功能。

较旧的、 更传统 Web 应用程序,这处理由传统的 ASP.NET 的性质 (或 Java servlet 或 Ruby 上 Rails 或 PHP 或...) 应用程序:所有内容是一个单独且完全不同网页的所制造的服务器上,则在发送到客户端进行呈现。在 SPA 中,但是,大多数 (如果不是全部) 呈现的操作是完全客户端,并仅返回到服务器时需要的数据或需要调用需要保持隐藏 (如修改数据的共享数据库中的服务器上消失,某些行为或可能调用单独的 Web 服务即可隐藏代表用户的防火墙后面)。

因此,在大多数 SPA 框架 — 如 Angular-另一种机制是为了提供类型的"作用域"或"分段"页边界提供必需的。从本质上讲,您需要某种类型的工具或机制来更改"页"中的 SPA,实质上翻录出当前显示任何组件和替换为一组不同的组件,以便对用户来说,它看起来你已更改的页,但是,而无需执行操作的 HTTP 往返,导航到新页通常涉及到。在 Angular,该机制称为"路由"和它是 Angular 的路由器的责任。(和您的课程。)

路由基础知识

若要更好地掌握如何路由的工作原理,让我们假设标准的大纲-细节风格的应用程序:第一页将显示通过某种总结我正在关注 (例如在会议上演讲者) 的项的列表 (如按姓氏和名字)。当用户想要"向下钻取"到更多详细显示中的单个项时,它们将单击该列表中的项,我将打开的更详细视图。在 Angular 术语中,这意味着我想要具有两个组件来处理: SpeakerListComponent,若要按名称和 SpeakerComponent,以显示该演讲者的完整详细信息显示演讲者。这是相当标准的母版-详细信息填充,并且更重要的是,它是无数的业务应用程序的中央主流产品。当然,有其他 (可能是更好) 的方式来构建业务 UI,但此选项可用于核心的观点,我需要找出如何将 SpeakerListComponent 路由到给定 SpeakerComponent,并传递在所选的演讲者,而我这样做。

开始使用路由的自然位置是使用自己的路由的集合。它是典型的愿望主页的应用程序"主"视图 (发言人列表),因此,让我们开始吧。因为路由通常是应用程序范围的某些内容或至少模块范围内,通常定义路由在 app.module.ts 文件中,通过构造一个路由对象,该对象从"@angular/routing"模块导入:

const appRoutes: Routes = [
  { path: 'speakers', component: SpeakerlistComponent }
];

请注意,路由的外观实质上是相同看在其他 Web 技术,如 ASP.NET MVC 或甚至 Rails 上的 Ruby。路由是核心,应显示的组件 (不带前导斜杠) 的 URL 路径的映射。因此,在此特定情况下,当用户导航到"http://localhost:4200//扬声器,"他们都将获得与大会的发言人列表。

细想起来,我想要重定向到"发言人"路由"/"的路径,以便进入"主页"会自动重定向到的发言人列表,因此,让我们添加的:

const appRoutes: Routes = [
  { path: 'speakers', component: SpeakerlistComponent },
  { path: '', redirectTo: '/speakers', pathMatch: 'full' }
];

当然,通常需要的其他操作是某种类型的"糟糕 !"页后,可以显示是否用户转到的 URL 不存在的在网站上,因此,您还需要一个"通配符"路由,将显示 PageNotFoundComponent 则必须通过夏天构建实习生:

const appRoutes: Routes = [
  { path: 'speakers', component: SpeakerlistComponent },
  { path: '', redirectTo: '/speakers', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent }
];

请注意通配符路由不会真正起来毫无差别,除了"* *"路径,但它会故意放在路由表的末尾。这是根据设计,因为计算路由自上而下的与第一个匹配"获取"。 因此,如果通配符路由在顶部,您会始终显示实习生的暑期工作,无论是否用户导航到正确的路由或未关闭。

最后,我需要设置一个路由以显示单个中发表演讲,并执行该操作的典型方法是为每位演讲者提供页面/路由使用某种形式的关联,类似于"/ 演讲者/1"与 ID 1 演讲者的唯一标识符。设置该路由将类似于具有任何熟悉 ASP.NET MVC 或 Rails,同样,任何人,可以使用冒号作为前缀的参数名称用作中传递的实际值的占位符:

const appRoutes: Routes = [
  { path: 'speaker/:id', component: SpeakerComponent },
  { path: 'speakers', component: SpeakerlistComponent },
  { path: '', redirectTo: '/speakers', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent }
];

左上该使用者仅真正的问题是如何 SpeakerComponent 获取的"id"参数;就在于有趣的故事。

ActivatedRoutes

当路由会介入并在屏幕上将一个组件时,ActivatedRoute 对象包含有关路由使用,包括到路由参数的信息 (如": id"之前使用)。与 Angular 中的大多数情况,一样 ActivatedRoute 是一个注射对象,因此,您可以向它 SpeakerComponent 的构造函数中要知道哪个扬声器,若要显示,如中所示图 1

图 1 要求提供构造函数中 ActivatedRoute

@Component({
  selector: 'app-speaker',
  templateUrl: './speaker.component.html',
  styleUrls: ['./speaker.component.css']
})
export class SpeakerComponent implements OnInit {
  @Input() speaker : Speaker
  constructor(private speakerService: SpeakerService,
    private route: ActivatedRoute) {
  }
  ngOnInit() {
    const speakerId = this.route.snapshot.params['id'];
    this.speaker = this.speakerService.getSpeakerById(speakerId);
  }
}

ActivatedRoute 很大程度包装在可观察的实体,这是不是我想要将导入更多,因此简单地说获取"快照"的路由的是最简单的方法来获取; 中的参数从此处我询问"id"参数,和"1"中的"/ 演讲者/1"交回给我与 SpeakerService 一起使用。

ActivatedRoute 可以运行通过多个不同的 URL 部分,顺便说一下,如果您感到奇怪-是否可以通过 URL 部分或片段或甚至查询参数映射路由。简短的答案是肯定的、 ActivatedRoute 可让你访问的 URL,您可能希望参数化,任何部分和详细的答案是,当然,查看 Angular 文档,了解所有详细信息。事实上,路由可以实际合并作为路由的一部分的任意数据和解决这些数据之前的路由的激活,但这就是一些最多的尝试的我有这一次讨论的可用空间。

路由器输出口和链接

缺少的内容仍?两个部分: 路由器获取执行其神奇功能,在 UI 中选择的位置和主列表和详细信息组件之间的链接。在模板文件,而不是 TypeScript 代码中会同时发生。

路由器才会出现的最常见位置前,通常是根目录中的应用程序,然后重试。也就是说,应用程序组件将最常定义路由器的各种组件应出现的位置。实际上,通常的应用程序组件将没有路由器的"空间",依此类推包围它的上方,其下方的页脚组件的标头组件。由"路由器电源插座"标记中,定义路由器的"空间",几乎就是始终为空 — 内部是路由的组件出现的位置,因此我 app.component.html 将如下所示:

<div style="text-align:center">
  <h1>
    Welcome to {{ title }}!
  </h1>
</div>
<h2>Welcome to our conference</h2>
<router-outlet></router-outlet>
<h6>No speakers are actually going to appear, so...</h6>

当然,会议网站上可以执行与功能改进,不过我要将此留给 Web 设计器。此处的关键在于,"路由器电源插座"标记对将被替换为 SpeakerlistComponent 或 SpeakerComponent,具体取决于使用路由。

必须完成的另外一点是将链接放入 SpeakerlistComponent,以便用户可以单击说话人的名称,转到其详细信息页。若要执行此操作的最简单方法是只需提供 SpeakerlistComponent 的模板中的定位点标记中的标准问题 href 如下所示:

<div>
  <div *ngFor="let speaker of speakers">
    <a href="/speaker/{{speaker.id}}">
      {{speaker.firstName}} {{speaker.lastName}}</a>
  </div>
</div>

并且,我们有一个基本的大纲-细节应用程序。

总结

没有更好地发现有关路由 — 它是一个复杂得多的主题不是我能够完全覆盖下面。例如,您还可以指定任意 (静态)"数据"参数时定义的路由集合,可以再选取激活的路由对象,或者您可以定义 Angular 称之为"解析 guard",它可以用于执行某些处理 (所选的演讲者,如检索数据) 时仍正在构造 UI。与往常一样,Angular 文档具有高成本的详细信息对于那些想了解详细信息。

现在,但是,我们已使用,我们母版-详细信息的方法,您现在为我们一部分方法个月。在下一步一集中,我们将讨论如何使用 Angular 的支持的自动测试来测试此 sucker。在此期间,祝你编码愉快 !


Ted Neward位于西雅图的 polytechnology 公司顾问、 发言人和导师,目前担任工程设计和开发者关系主管Smartsheet.com。他撰写了大量文章,创作和与人合著过十几本书,并在世界各地发表演讲。可通过 ted@tedneward.com 与他联系,也可阅读他的博客 blogs.tedneward.com

衷心感谢以下技术专家:Garvice Eakins (Smartsheet.com)


在 MSDN 杂志论坛讨论这篇文章