[Angular Tutorial] 9 -Routing & Multiple Views

时间:2022-09-19 23:57:29

在这一步中,您将学到如何创建一个布局模板,并且学习怎样使用一个叫做ngRoute的Angular模块来构建一个具有多重视图的应用。

  ·当您现在访问/index.html,您将被重定向到/index.html#!/phones,电话列表会显示在浏览器中;

  ·当您点击一部电话的超链接,URL会改变至该指定电话,浏览器将展示一个简短的电话细节页面。

最大的不同列举如下,您可以点击这里在GitHub上查看全部的不同。

依赖

这一步中添加的路由功能是由Angular中的ngRoute模块提供的,该模块由核心的Angular框架独立出来。

由于我们使用Bower来安装客户端的依赖,该步中我们更新bower.json配置文件来添加新的依赖:

bower.json:

{
"name": "angular-phonecat",
"description": "A starter project for AngularJS",
"version": "0.0.0",
"homepage": "https://github.com/angular/angular-phonecat",
"license": "MIT",
"private": true,
"dependencies": {
"angular": "1.5.x",
"angular-mocks": "1.5.x",
"angular-route": "1.5.x",
"bootstrap": "3.3.x"
}
}

新的依赖"angular-route": "1.5.x"告诉bower去安装一个与Angular1.5.x版本兼容的angular-route模块版本。我们必须告诉bower去下载和安装这些依赖。

npm install

多重视图,路由和布局模板

我们的应用正在逐步变得复杂。在这一步之前,应用为我们的用户提供了一个单页视图(包括电话列表),并且所有的模板代码都位于phone-list.template.html文件下。构建应用的下一步,是添加一个能展示我们列表中每一部电话的细节的视图。

为了添加细节视图,我们将index.html转换成一个我们称之为“布局模板”的模板,一个于我们应用中所有视图都公共的模板。其他被包含在该布局模板中的“局部模板”依赖于当前的“路由”--当前展示给用户的视图。

Angular应用间的路由通过$routeProvider声明,这被$route服务所提供。该服务使得将控制器,视图模板和当前浏览器的URL捆绑起来变得容易。使用这点特性,我们可以实现深度链接,这使得我们可以充分利用浏览器的历史记录(前进和后退的导航)以及电子书签。

关于依赖注入,注入器和提供者的笔记

正如你注意到的,依赖注入在Angular中处于核心地位,所以对你来说深入了解它是很重要的。

在引导应用时,Angular创建一个注入器,这被用于找到和注入您应用中需要被用到的服务。注入器本身并不知道$http或$route这些服务做了什么。事实上,注入器甚至不知道这些服务的存在,除非它被适当的模块定义所配置。

注入器只执行了下面的步骤:
  ·加载您在应用中指定的模块定义;

  ·注册这些模块定义中定义的所有提供者;

  ·一旦被要求这么做,通过提供者,这作为可注入的函数中的参数,来懒惰式(lazily,需要时才加载)实例化服务和他们的依赖。

提供者是用来提供(创建)服务实例和对外配置API的对象,这可以被用来控制一个服务创建和运行时的行为。对于$route服务来说,$routeProvider提供API来允许您定义您应用中的路由。

(注意:提供者仅仅能被注入config函数,因此您不能在运行时将$routeProvider注入PhoneListController。)

Angular模块解决了从应用中移除全局变量的问题并且提供了配置注入器的方法。与AMD或require.js模块不同的是,Angular模块不会去试图解决脚本加载顺序或懒惰式脚本获取的问题。这些目标是完全独立的,并且每一个模块系统能并肩运作来实现他们的目标。

为了深入您对Angular依赖注入的理解,请看这里。

模板

$route服务经常和ngView指令结合使用。ngView指令扮演的角色是将当前路由的视图模板包含进布局模板。这使得其和我们的index.html完美契合。

app/index.html:

<head>
...
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="app.module.js"></script>
<script src="app.config.js"></script>
...
<script src="phone-detail/phone-detail.module.js"></script>
<script src="phone-detail/phone-detail.component.js"></script>
</head>
<body> <div ng-view></div> </body>

我们添加了4个额外的<script>标签来在我们的应用中加载额外的JavaScript文件:
  ·angular-route.js:定义了Angular的ngRoute模块,这为我们提供路由;

  ·app.config.js:为我们的主模块配置提供者(参见下文);

  ·phone-detail.module.js:定义了一个包含phoneDetail组件的新模块;

  ·phone-detail.component.js:定义了一个phoneDetail组件的模型(参见下文)。

注意到我们在index.html模板中移除了<phone-list></phone-list>一行并且用一个包含ng-view属性的div来替换它。

[Angular Tutorial] 9 -Routing & Multiple Views

配置一个模块

模块的.config()方法为我们提供了获取用于配置的提供者的入口。为了在我们的应用中获取定义于ngRoute的提供者,服务和指令,我们需要在我们的phonecatApp模块中将ngRoute添加为一个依赖。

app/app.module.js:

angular.module('phonecatApp', [
'ngRoute',
...
]);

现在,除了核心的服务和指令,我们也能为我们的应用配置$route服务(使用其提供者)。为了能迅速定位配置代码,我们将其列为一个单独的文件并且添加.config后缀。

app/app.config.js:

angular.
module('phonecatApp').
config(['$locationProvider', '$routeProvider',
function config($locationProvider, $routeProvider) {
$locationProvider.hashPrefix('!'); $routeProvider.
when('/phones', {
template: '<phone-list></phone-list>'
}).
when('/phones/:phoneId', {
template: '<phone-detail></phone-detail>'
}).
otherwise('/phones');
}
]);

通过使用.config()方法,我们请求将必要的提供者( 比如$routeProvider)注入到我们的配置函数,然后使用它们的方法来制定对应服务的行为。在这里,我们使用$routeProvider.when()$routeProvider.otherwise()方法来指定我们的应用路由。

我们的路由定义如下:

  ·when('/phones'):决定将被展示的视图,当URL的哈希片段为/phones。通过指定的模板,Angular会创建一个phoneList组件的实例来管理视图。注意到这和我们在index.html使用的是相同的标记。

  ·when('/phones/:phoneId'):决定将被展示的视图,当URL的哈希片段为/phones/<phoneId>, <phoneId>是URL中变化的部分。管理phoneDetail组件中的视图。

  ·otherwise('/phones'):定义一个指向的回退路由,当没有被定义的路由于当前URL匹配。(这里会指向/phones)。

我们复用了我们已经构建的phoneList组件和一个新的“模型”phoneDetail组件。到目前为止,phoneDetail组件仅仅会展示选中电话的ID。(不是那么令人印象深刻,我们会在下一步中扩展它)。

注意到:phoneId作为路由声明的第二个参数,$route服务使用路由声明--'/phones/:phoneId'--作为一个与当前URL相匹配的模板。所有用:前缀定义的变量都被提取进入了$routeParams对象。

phoneDetail组件

我们创建了一个phoneDetail组件来处理电话细节视图。我们遵循和phoneList一样的惯例:使用一个独立的模块来创建phoneDetail模块,这在我们的phonecatApp模块中被添加为依赖。

app/phone-detail/phone-detail.module.js:

angular.module('phoneDetail', [
'ngRoute'
]);

app/phone-detail/phone-detail.component.js:

angular.
module('phoneDetail').
component('phoneDetail', {
template: 'TBD: Detail view for <span>{{$ctrl.phoneId}}</span>',
controller: ['$routeParams',
function PhoneDetailController($routeParams) {
this.phoneId = $routeParams.phoneId;
}
]
});

app/app.module.js:

angular.module('phonecatApp', [
...
'phoneDetail',
...
]);

一点关于子模块依赖的笔记

phoneDetail模块依赖于ngRoute模块,以此来提供$routeParams对象,这被用于phoneDetail组件的控制器中。由于ngRoute也是主模块phonecatApp中的依赖,其服务和指令在整个应用中都是可获取的(包括phoneDetail组件)。

这意味着及时我们不为phoneDetail组件的依赖列表中引入ngRoute,我们的应用依然可以正常工作。虽然删除子模块中哪些已经在主模块中引入的依赖听上去还不错,但这却损害了我们来之不易的模块化。

此处的额外知识是:

  ·永远清楚描述一个子模块的所有依赖。不要依赖于任何继承于父模块的依赖。(因为父模块可能哪天就不见了。)

总结

随着路由的建立和电话列表视图的实现,让我们进入下一步来实现一个正确的电话细节列表。

[Angular Tutorial] 9 -Routing & Multiple Views的更多相关文章

  1. Routing&lpar;路由&rpar; &amp&semi; Multiple Views&lpar;多个视图&rpar; step 7

    Routing(路由) & Multiple Views(多个视图) step 7 1.切换分支到step7,并启动项目 git checkout step-7 npm start 2.需求: ...

  2. &lbrack;Angular Tutorial&rsqb;PhoneCat Tutorial App

    (注:曾经在<不敢止步>一书中看到学到一个观点,作者认为学习一门技术最好的方法就是翻译某部领域书籍.这里我决定做一次尝试,接下来花1个月左右时间,将Angular Tutorial Pho ...

  3. AngularJS学习---Routing&lpar;路由&rpar; &amp&semi; Multiple Views&lpar;多个视图&rpar; step 7

    1.切换分支到step7,并启动项目 git checkout step- npm start 2.需求: 在步骤7之前,应用只给我们的用户提供了一个简单的界面(一张所有手机的列表),并且所有的模板代 ...

  4. &lbrack;Angular Tutorial&rsqb; 3-Components

    在先前的步骤中,我们看到了一个控制器和一个模板如何一起工作来将一个静态的HTML文件转化为动态页面(view).一般说来,这在单页应用中一种非常常见的模式(在Angular应用中尤其是这样): ·客户 ...

  5. &lbrack;Angular Tutorial&rsqb; 7-XHRs &amp&semi; Dependency Injection

    我们受够了在应用中用硬编码的方法嵌入三部电话!现在让我们用Angular内建的叫做$http的服务来从我们的服务器获取更大的数据集吧.我们将会使用Angular的依赖注入来为PhoneListCtrl ...

  6. &lbrack;Angular Tutorial&rsqb; 0-Bootstraping

    在这一节的tutorial中,您将会逐渐熟悉AngularJS phonecat app的最重要的源代码文件.您也将学到如何将开发服务器与angular-seed绑定到一起,并且在浏览器中运行应用. ...

  7. angular 2 - 004 routing 路由

    https://angular.io/tutorial/toh-pt5 定义一个模块用来定义路由 src/app/app-routing.module.ts import { NgModule } f ...

  8. &lbrack;Angular 2&rsqb; Pipes with Multiple Parameters

    Showing how to set up a Pipe that takes multiple updating inputs for multiple Component sources. imp ...

  9. &lbrack;Angular Tutorial&rsqb; 14 -Animations

    在这一步中,我们将会通过在我们先前创建的模板代码中添加CSS和JavaScript动画效果来扩展我们的web应用. ·我们现在使用ngAnimate模块来允许动画效果贯穿整个应用. ·我们也依赖于自带 ...

随机推荐

  1. svn 几个常用命令(持续更新)

    1:获取某个版本号(3583)下的代码                                               svn co http://tech.yoai.com:8300/c ...

  2. 2、为Eclipse绑定Tomcat

    1.window→preferences打开属性窗口 2.点击add 3.点击Tomcat6.0 点击next 4.选择tomcat的解压目录和jdk,并点击finish 5.点击ok 6.打开ser ...

  3. web开发路径问题

    1. web开发路径问题总结: http://www.cnblogs.com/tianguook/archive/2012/08/31/2665755.html 2. JSP/SERVLET 路径问题 ...

  4. navicat 导出mysql表结构

    选中需要导出表结构的数据库,右键,在显示的菜单中选择“数据传输”这一项 ,在弹出窗口中“数据传输”单击选择“高级”一项,在“高级”中把“记录选项”中的勾去掉,在做一些设置,最后导出表数据就不会导出记录 ...

  5. tox环境安装

    ubuntu 下安装tox环境 1.apt-get install pip 2.pip install tox 3.git git clone https://github.com/openstack ...

  6. manacher模板(manacher&rpar;

    洛谷题目传送门 写完有一段时间了,发现板子忘记存在了这里...... 算法简述 一种字符串算法,\(O(n)\)高效求出以每个字符为对称中心的最长回文串长度. 然后,就可以进一步求出全串中最长回文串的 ...

  7. Bootstrap table方法,Bootstrap table事件,配置

    调用 BootStrap Table 方法的语法: $('#table').bootstrapTable('method', parameter); 例如: $('#my_table').bootst ...

  8. 机器学习技法笔记:12 Neural Network

    Roadmap Motivation Neural Network Hypothesis Neural Network Learning Optimization and Regularization ...

  9. js使用中的小问题----textarea是否有value属性

    使用jquery的选择器时想给textarea设置一个默认值时,采取了下面的方法: 不过失败了,但是看教程上确实成功的,那么肯定是有问题的. 经过上网查找以及自己验证发现: 1.textarea标签确 ...

  10. es6&lpar;13&rpar;--Promise

    //Promise { //原始方法 let ajax=function(callback){ console.log('执行') setTimeout(function(){ callback&am ...