这是SitePoint Angular 2教程的第4部分,介绍了如何使用Angular CLI创建CRUD应用程序。在本文中,我们将介绍Angular路由器,并了解当浏览器URL更改时如何更新我们的应用程序,反之亦然。我们还将学习如何使用路由器更新我们的应用程序以从后端API解决数据。
在第一部分中,我们学会了如何将待办器应用程序启动,运行并部署到github页面。这效果很好,但是不幸的是,整个应用都被挤入了一个组件。 在第二部分中,我们检查了一个更模块化的组件体系结构,并学习了如何将这个单个组件分解为一个较小的组件的结构化树,这些成分易于理解,重复使用和维护。 在第三部分中,我们更新了应用程序,以使用RXJ和Angular的HTTP服务与REST API后端进行通信。
第0部分 - 终极角度CLI参考指南
第1部分 - 获取我们的第一个todo应用程序启动和运行
>因此,要启动并运行(已安装了Angular CLI的最新版本),我们将执行此操作:
><span>npm install -g @angular/cli@latest </span>
然后访问http:// localhost:4200/。如果一切顺利,您应该看到工作的todo应用程序。
npm uninstall -g @angular/cli angular-cli npm cache clean <span>npm install -g @angular/cli@latest </span>快速回顾
这是我们的应用程序体系结构在第3部分的末尾的样子:
在本文中,我们将:
>何时以及为什么您的应用程序可能需要路由
>我们通过一个URL访问我们的应用程序,例如http:// localhost:4200,我们的应用程序不知道任何其他URL,例如http:// localhost:4200/todos。
>大多数Web应用程序都需要支持不同的URL,以将用户导航到应用程序中的不同页面。那是路由器进来的地方。一个用户单击浏览器中的链接,导致URL更改
>
浏览器将HTTP请求发送到服务器服务器从HTTP请求读取URL并生成适当的HTTP响应
服务器将http响应发送到浏览器。
> JavaScript路由器使我们有可能开发单页应用程序(SPA)。
>用户从一个页面导航到另一页时,即使URL更改,该页面也会动态更新,而无需重新加载。
。首先,Angular Router负责JavaScript路由器的职责:
>当用户导航到某个URL
在激活或停用页面时运行脚本
lazy load Load我们应用程序的部分。>的浏览器URL
它应用URL重定向(如果定义了)>
它可以弄清哪个路由器状态对应于url>它可以解决路由器状态
的所需数据
它激活角组件以显示页面启用路由
要在我们的角度应用中启用路由,我们需要做三件事:
创建一个路由配置,该配置为我们的应用程序定义了可能的状态
添加一个路由器插座,以告诉角路由器将激活的组件放在dom。
的列表
>所以让我们列出我们的待办事项清单自己的URL,然后将我们的主页重定向到其中:
/:重定向到 /todos
官方Angular样式指南建议将Angular模块的路由配置存储在文件中,并在-routing.module.ts中输出文件名,该文件名导出一个单独的Angular模块,并在routingModule中结束名称。
我们的当前模块称为AppModule,因此我们创建一个文件src/app/app-routing.module.ts,并将路由配置导出为称为apploutingModule的角度模块:
<span>npm install -g @angular/cli@latest </span>首先,我们从 @angular/Router导入Routermodule和路由:
接下来,我们定义一个类型路由的可变路由并分配我们的路由器配置:
npm uninstall -g @angular/cli angular-cli npm cache clean <span>npm install -g @angular/cli@latest </span>
>
<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git </span><span>cd angular-todo-app </span><span>git checkout part-3 </span><span>npm install </span>ng serve路由类型是可选的,可以让IDEScript支持或打字稿编译器在开发过程中方便地验证您的路线配置。
>
路由器配置表示我们的应用程序中所有可能的路由器状态。它是一棵路由树,定义为JavaScript数组,每个路线都可以具有以下属性:
路径:字符串,匹配URL
的路径>在这里,Todos有两个子路由,ID是一个路由参数,使路由器能够识别以下URL:
<span>import { NgModule } from '@angular/core'; </span><span>import { RouterModule, Routes } from '@angular/router'; </span><span>import { AppComponent } from './app.component'; </span> <span>const routes: Routes = [ </span> <span>{ </span> path<span>: '', </span> redirectTo<span>: 'todos', </span> pathMatch<span>: 'full' </span> <span>}, </span> <span>{ </span> path<span>: 'todos', </span> component<span>: AppComponent </span> <span>} </span><span>]; </span> <span><span>@NgModule</span>({ </span> imports<span>: [RouterModule.forRoot(routes)], </span> exports<span>: [RouterModule], </span> providers<span>: [] </span><span>}) </span><span>export class AppRoutingModule { </span><span>} </span>
/:主页,重定向到 /todos
>前缀:默认值,匹配url时,从路径的值开始
完整:匹配URL等于路径的值时匹配。我们可以创建以下途径:
>我们只希望将主页重定向到Todos,因此我们添加路径:'Full'以确保仅匹配的URL'
<span>npm install -g @angular/cli@latest </span>>要了解有关不同路由配置选项的更多信息,请查看有关路由和导航的官方角文档。
>
最后,我们创建和导出一个角模块批准模块:
有两种创建路由模块的方法:
npm uninstall -g @angular/cli angular-cli npm cache clean <span>npm install -g @angular/cli@latest </span>
routermot.forroot(路由):创建一个包括路由器指令,路由配置和路由器服务
>的路由模块>当我们导入使用Routermot.forroot()创建的路由模块时,Angular将实例化路由器服务。当我们导入使用routermodule.forchild()创建的路由模块时,Angular将不会实例化路由器服务。
>因此,我们只能使用routermot.forroot()一次,然后多次使用routermot.forchild.forchild.forchild()进行其他路由模块。
>由于我们的应用程序只有一个路由模块,因此我们使用routermotule.forroot():
>此外,我们还指定了导出属性中的routermodule:
这可以确保我们不必在AppModule imports ApploutingModule时再次在AppModule中明确导入Routermodule。
<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git </span><span>cd angular-todo-app </span><span>git checkout part-3 </span><span>npm install </span>ng serve>现在我们有了批准模块,我们需要在AppModule中导入它才能启用它。
导入路由配置
<span>import { NgModule } from '@angular/core'; </span><span>import { RouterModule, Routes } from '@angular/router'; </span><span>import { AppComponent } from './app.component'; </span> <span>const routes: Routes = [ </span> <span>{ </span> path<span>: '', </span> redirectTo<span>: 'todos', </span> pathMatch<span>: 'full' </span> <span>}, </span> <span>{ </span> path<span>: 'todos', </span> component<span>: AppComponent </span> <span>} </span><span>]; </span> <span><span>@NgModule</span>({ </span> imports<span>: [RouterModule.forRoot(routes)], </span> exports<span>: [RouterModule], </span> providers<span>: [] </span><span>}) </span><span>export class AppRoutingModule { </span><span>} </span>
>要将我们的路由配置导入应用程序,我们必须将批准模块导入我们的主要AppModule。
>让我们打开src/app/app.module.ts,然后将ApploutingModule添加到AppModule的@ngmodule metadata中的导入阵列:>
)。
)。>在我们可以在浏览器中尝试更改之前,我们需要完成第三步也是最后一步。
添加路由器插座<span>import { RouterModule, Routes } from '@angular/router'; </span>
尽管我们的应用程序现在具有路由配置,但我们仍然需要告诉Angular Router,它可以将实例化组件放置在DOM中。当我们的应用程序被引导时,Angular会启用AppComponent时,因为AppComponent在AppModule的Bootstrap属性中列出
告诉角路由器可以放置组件的位置,我们必须将 元素添加到AppComponent的HTML模板中。
<span>npm install -g @angular/cli@latest </span>
>如果您熟悉AngularJS 1.x路由器和UI-Router,则可以考虑
没有
但我们现在希望AppComponent包含AppComponent,而不是让AppComponent显示todos的列表,而是包含 ,并告诉Angular Router以实例化AppComponent中的另一个组件以显示Todos列表。 🎜> 为了实现这一目标,让我们使用Angular CLI生成一个新的组件todoscomponent:
>我们还将所有HTML从src/app/app.component.html移动到src/app/todos/todos/todos.component.html:
>我们还将所有逻辑从src/app/app.component.ts移动到src/app/todos/todos/todos.component.ts:
现在,我们可以在src/app/app.component.html中替换appcomponent的模板:
npm uninstall -g @angular/cli angular-cli npm cache clean <span>npm install -g @angular/cli@latest </span>
>我们还可以从src/app/app.component.ts中的AppComponent类中删除所有已过时的代码:
<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git </span><span>cd angular-todo-app </span><span>git checkout part-3 </span><span>npm install </span>ng serve
最后,我们在src/app/app-routing.module.ts中更新我们的todos路由,以实例化todoscomponent,而不是appcomponent:
<span>import { NgModule } from '@angular/core'; </span><span>import { RouterModule, Routes } from '@angular/router'; </span><span>import { AppComponent } from './app.component'; </span> <span>const routes: Routes = [ </span> <span>{ </span> path<span>: '', </span> redirectTo<span>: 'todos', </span> pathMatch<span>: 'full' </span> <span>}, </span> <span>{ </span> path<span>: 'todos', </span> component<span>: AppComponent </span> <span>} </span><span>]; </span> <span><span>@NgModule</span>({ </span> imports<span>: [RouterModule.forRoot(routes)], </span> exports<span>: [RouterModule], </span> providers<span>: [] </span><span>}) </span><span>export class AppRoutingModule { </span><span>} </span>
现在,当我们的应用程序被引导时,Angular启用了AppComponent并找到
<span>import { RouterModule, Routes } from '@angular/router'; </span>>。
>让我们在浏览器中尝试更改。
><span>const routes: Routes = [ </span> <span>{ </span> path<span>: '', </span> redirectTo<span>: 'todos', </span> pathMatch<span>: 'full' </span> <span>}, </span> <span>{ </span> path<span>: 'todos', </span> component<span>: AppComponent </span> <span>} </span><span>]; </span>>通过运行:
启动开发服务器和后端API
<span>const routes: Routes = [ </span> <span>{ </span> path<span>: '', </span> redirectTo<span>: 'todos', </span> pathMatch<span>: 'full' </span> <span>}, </span> <span>{ </span> path<span>: 'todos', </span> children<span>: [ </span> <span>{ </span> path<span>: '', </span> component<span>: 'TodosPageComponent' </span> <span>}, </span> <span>{ </span> path<span>: ':id', </span> component<span>: 'TodoPageComponent' </span> <span>} </span> <span>] </span> <span>} </span><span>]; </span>然后将浏览器导航到http:// localhost:4200。
> Angular路由器读取路由器配置,并自动将我们的浏览器重定向到http:// localhost:4200/todos。
如果您检查页面上的元素,您会看到todosComponent在
我们的应用程序现在已启用路由。太棒了!
<span>// no pathMatch specified, so Angular Router applies </span><span>// the default `prefix` pathMatch </span><span>{ </span> path<span>: '', </span> redirectTo<span>: 'todos' </span><span>} </span>添加通配符路线
>当您将浏览器导航到http:// localhost:4200/tormatched-url,并且您打开浏览器的开发人员工具时,您会注意到,Angular Router将以下错误记录到控制台:
>
才能优雅地处理无与伦比的URL,我们需要做两件事: 然后在src/app/page-not-not/page-not-found.component.html中编辑其模板: 接下来,我们使用**作为路径添加通配符路线: 现在,如果您将浏览器导航到http:// localhost:4200/tormatched-url,则显示PagenotfoundComponent。
将永远无法达到戒酒,并且将显示pagenotfoundcomponent,因为通配符路线将首先匹配。 我们已经做了很多事情,所以让我们快速回顾到目前为止取得的成就: 我们设置了Angular Router
<span>npm install -g @angular/cli@latest
</span>
npm uninstall -g @angular/cli angular-cli
npm cache clean
<span>npm install -g @angular/cli@latest
</span>
<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git
</span><span>cd angular-todo-app
</span><span>git checkout part-3
</span><span>npm install
</span>ng serve
当Angular路由器匹配请求URL与路由器配置匹配时,它在找到第一个匹配时就会停止处理。<span>import { NgModule } from '@angular/core';
</span><span>import { RouterModule, Routes } from '@angular/router';
</span><span>import { AppComponent } from './app.component';
</span>
<span>const routes: Routes = [
</span> <span>{
</span> path<span>: '',
</span> redirectTo<span>: 'todos',
</span> pathMatch<span>: 'full'
</span> <span>},
</span> <span>{
</span> path<span>: 'todos',
</span> component<span>: AppComponent
</span> <span>}
</span><span>];
</span>
<span><span>@NgModule</span>({
</span> imports<span>: [RouterModule.forRoot(routes)],
</span> exports<span>: [RouterModule],
</span> providers<span>: []
</span><span>})
</span><span>export class AppRoutingModule {
</span><span>}
</span>
我们为应用程序创建了路由配置
的空数组
在thetodoscomponent的ngoninit处理程序的API中获取戒酒如果在步骤5中加载Todos需要三秒钟,则将在步骤6中显示实际的Todos之前,在三秒钟内显示用户三秒钟的空白列表。
如果todoScomponent在其模板中具有以下HTML:
>我们可以将加载程序添加到todosComponent,该加载程序在加载数据时显示旋转器,但有时我们可能无法控制实际组件,例如,当我们使用第三方组件时。
要解决这种不必要的行为,我们需要以下以下事情:>
中获取招待
>告诉Angular路由器在激活Todos Coute中的TodoScomponent时,使用TodoSresolver来获取毒品。>
>通过将解析器连接到Todos路线,我们要求Angular路由器首先解析数据,然后再激活TodoScomponent。
因此,让我们创建一个解析器来获取我们的戒酒。解决方案接口是可选的,但是让我们的打字稿IDE或编译器确保我们通过要求我们实现resolve()方法来正确实现类。
TodoSresolver的代码非常简洁,因为我们已经有一个与API后端进行所有通信的TodoDataservice。
我们在构造函数中注入tododataservice,并使用其getalltodos()方法在resolve()方法中获取所有todos。<span>npm install -g @angular/cli@latest </span>解决方法返回可观察到的todo []的可观察的方法,因此Angular路由器将在激活路线组件之前等待可观察到的可观察到的。
>现在我们有了解决方案,让我们配置Angular路由器以使用它。 要使角路由器使用解析器,我们必须将其连接到路线配置中的路由。
这告诉Angular路由器使用TodoSresolver解析数据,并将解析器的返回值分配为路由数据中的Todos。
>角路由器使用角度依赖注入来访问解析器,因此我们必须通过将其添加到AcressutingModule的@ngmodule Metadata中:
重定向URL
激活todosComponent。解决戒酒
<span>npm install -g @angular/cli@latest
</span>
我们导入todosresolver:npm uninstall -g @angular/cli angular-cli
npm cache clean
<span>npm install -g @angular/cli@latest
</span>
<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git
</span><span>cd angular-todo-app
</span><span>git checkout part-3
</span><span>npm install
</span>ng serve
>您可以使用路由的数据属性直接将静态数据添加到路由数据:<span>import { NgModule } from '@angular/core';
</span><span>import { RouterModule, Routes } from '@angular/router';
</span><span>import { AppComponent } from './app.component';
</span>
<span>const routes: Routes = [
</span> <span>{
</span> path<span>: '',
</span> redirectTo<span>: 'todos',
</span> pathMatch<span>: 'full'
</span> <span>},
</span> <span>{
</span> path<span>: 'todos',
</span> component<span>: AppComponent
</span> <span>}
</span><span>];
</span>
<span><span>@NgModule</span>({
</span> imports<span>: [RouterModule.forRoot(routes)],
</span> exports<span>: [RouterModule],
</span> providers<span>: []
</span><span>})
</span><span>export class AppRoutingModule {
</span><span>}
</span>
>一旦解决了分解属性的解析器,它们的值就与数据属性中的静态数据合并,并将所有数据作为路线的数据提供。
<span>import { RouterModule, Routes } from '@angular/router';
</span>
>,确保将其添加到Angular的依赖注入系统中:
<span>const routes: Routes = [
</span> <span>{
</span> path<span>: '',
</span> redirectTo<span>: 'todos',
</span> pathMatch<span>: 'full'
</span> <span>},
</span> <span>{
</span> path<span>: 'todos',
</span> component<span>: AppComponent
</span> <span>}
</span><span>];
</span>
<span>const routes: Routes = [
</span> <span>{
</span> path<span>: '',
</span> redirectTo<span>: 'todos',
</span> pathMatch<span>: 'full'
</span> <span>},
</span> <span>{
</span> path<span>: 'todos',
</span> children<span>: [
</span> <span>{
</span> path<span>: '',
</span> component<span>: 'TodosPageComponent'
</span> <span>},
</span> <span>{
</span> path<span>: ':id',
</span> component<span>: 'TodoPageComponent'
</span> <span>}
</span> <span>]
</span> <span>}
</span><span>];
</span>
>从TodoSresolver运行Resolve()方法,等待结果,并将结果分配给路由数据中的Todos
>要访问路由数据,我们必须从 @angular/Router导入ActivatedRoute:
任务完成了!我们已经成功地集成了Angular路由器!
>在总结之前,让我们进行单元测试:
一个单位测试失败:
<span>npm install -g @angular/cli@latest </span>
>测试todoScomponent时,测试台不了解todolistheadercomponent,因此Angular抱怨它不知道App-todo-list-Header元素。
为了解决此错误,让我们打开应用程序/src/todos/todos.component.spec.ts,然后添加no_errors_schema到测试床选项:npm uninstall -g @angular/cli angular-cli npm cache clean <span>npm install -g @angular/cli@latest </span>
现在,业力显示了另一个错误:
>让我们将必要的提供商添加到测试床选项中:
<span>git clone git@github.com:sitepoint-editors/angular-todo-app.git </span><span>cd angular-todo-app </span><span>git checkout part-3 </span><span>npm install </span>ng serve
这再次引起了另一个错误:
<span>import { NgModule } from '@angular/core'; </span><span>import { RouterModule, Routes } from '@angular/router'; </span><span>import { AppComponent } from './app.component'; </span> <span>const routes: Routes = [ </span> <span>{ </span> path<span>: '', </span> redirectTo<span>: 'todos', </span> pathMatch<span>: 'full' </span> <span>}, </span> <span>{ </span> path<span>: 'todos', </span> component<span>: AppComponent </span> <span>} </span><span>]; </span> <span><span>@NgModule</span>({ </span> imports<span>: [RouterModule.forRoot(routes)], </span> exports<span>: [RouterModule], </span> providers<span>: [] </span><span>}) </span><span>export class AppRoutingModule { </span><span>} </span>
>让我们再添加一个用于ActivatedRoute的提供商到测试台选项:
<span>import { RouterModule, Routes } from '@angular/router'; </span>
我们为ActivatedRoute分配了一个模拟对象的提供商,该对象包含可观察的数据属性,以揭示Todos的测试值。
现在,单元测试成功通过:<span>const routes: Routes = [ </span> <span>{ </span> path<span>: '', </span> redirectTo<span>: 'todos', </span> pathMatch<span>: 'full' </span> <span>}, </span> <span>{ </span> path<span>: 'todos', </span> component<span>: AppComponent </span> <span>} </span><span>]; </span>
神话般!要将我们的应用程序部署到生产环境中,我们现在可以运行:
<span>const routes: Routes = [ </span> <span>{ </span> path<span>: '', </span> redirectTo<span>: 'todos', </span> pathMatch<span>: 'full' </span> <span>}, </span> <span>{ </span> path<span>: 'todos', </span> children<span>: [ </span> <span>{ </span> path<span>: '', </span> component<span>: 'TodosPageComponent' </span> <span>}, </span> <span>{ </span> path<span>: ':id', </span> component<span>: 'TodoPageComponent' </span> <span>} </span> <span>] </span> <span>} </span><span>]; </span>
我们将生成的DIST目录上传到我们的托管服务器。那有多甜?
>
我们在本文中介绍了很多,所以让我们回顾一下我们学到的东西。<span>// no pathMatch specified, so Angular Router applies </span><span>// the default `prefix` pathMatch </span><span>{ </span> path<span>: '', </span> redirectTo<span>: 'todos' </span><span>} </span>摘要
在第一篇文章中,我们学会了如何:
<span>{ </span> path<span>: '', </span> redirectTo<span>: 'todos', </span> pathMatch<span>: 'full' </span><span>} </span>
>使用Angular Cli
初始化我们的TODO应用程序创建一个todo类来表示单个todos
使用AppComponent组件显示用户界面
>
更新AppComponent以处理异步API调用
推荐课程
角度和打字稿的在线课程 托德座右铭 专家领导的在线AngularJ,为个人和团队提供的角度和打字稿培训课程。结帐时使用优惠券代码“ SitePoint”以获得25%的折扣。
经常询问的问题(常见问题解答)关于使用Angular Router的组件路由
我可以在Angular Router中的路由之间传递数据吗?使用称为路由参数的功能之间的路由之间的数据。路由参数是可以更改的URL的一部分,组件可以使用其值来动态显示内容或确定行为。当您想导航到列表中的项目的详细信息时,这特别有用。
> Angular Router如何处理浏览器历史记录和返回按钮功能?通过位置服务与浏览器的历史记录进行交互。它使用HTML5历史记录API更改URL而不会引起整页重新加载。这意味着浏览器的背部和前向按钮将按预期工作,在应用程序状态之间导航。
是的,是的,Angular路由器支持Lazy Loading。模块。这意味着您的应用程序的某些模块可以按需加载,而不是在应用程序的初始负载下加载。这可以显着提高应用程序的初始负载性能。
>我可以在Angular路由器中使用嵌套路由吗? 。这使您可以创建更复杂的导航结构,其中某些路线具有与之关联的子路由。这对于创建层次导航结构特别有用。
我可以预紧装置模块以在Angular Router中更快导航吗?特征称为预加载模块的预加载策略。这意味着在应用程序的初始负载之后,可以将某些模块加载到后台。这可以大大提高应用程序的导航速度,因为在需要时已经加载了这些模块。
以上是角路由器:组件路由的简介的详细内容。更多信息请关注PHP中文网其他相关文章!