上一课的例子中,我们的模型数据是硬编码的,也就是说,我们的数据不是从服务器请求回来的。

这里,我们先讲解,如何从服务器获取数据:

function PhoneListCtrl($scope, $http) {
  $http.get('phones/phones.json').success(function(data) {
    $scope.phones = data;
  });

  $scope.orderProp = 'age';
}

上一课的例子,我们只需要改写这个控制器构造函数就行了。

$http向Web服务器发起一个HTTP GET请求,获取phone/phones.json。AngularJS会自动检测这个应答是什么格式的,并且帮我们解析出来!

为了使用AngularJS的服务,你只需要在控制器的构造函数里面传入所需服务的名字。

当控制器构造的时候,AngularJS的依赖注入器会将这些服务注入到你的控制器中。

由于AngularJS是通过控制器构造函数的参数名字来推断依赖服务名称的。所以如果你要压缩PhoneListCtrl控制器的JS代码,它所有的参数也同时会被压缩,这时候依赖注入系统就不能正确的识别出服务了。

为了克服压缩引起的问题,只要在控制器函数里面给$inject属性赋值一个依赖服务标识符的数组,就像:

PhoneListCtrl.$inject = ['$scope', '$http'];
另一种方法也可以用来指定依赖列表并且避免压缩问题——使用Javascript数组方式构造控制器:把要注入的服务放到一个字符串数组(代表依赖的名字)里,数组最后一个元素是控制器的方法函数:

var PhoneListCtrl = ['$scope', '$http', function($scope, $http) { /* constructor body */ }];
上面提到的两种方法都能和AngularJS可注入的任何函数完美协作,要选哪一种方式完全取决于你们项目的编程风格,建议使用数组方式。

然后,我们为手机列表的手机数据项添加缩略图以及链接:

[
  {
    ...
    "id": "motorola-defy-with-motoblur",
    "imageUrl": "img/phones/motorola-defy-with-motoblur.0.jpg",
    "name": "Motorola DEFY\u2122 with MOTOBLUR\u2122",
    ...
  },
  ...
]

html改成这样:

...
<ul class="phones">
  <li ng-repeat="phone in phones | filter:query | orderBy:orderProp" class="thumbnail">
    <a href="#/phones/{{phone.id}}" class="thumb">

      <img ng-src="{{phone.imageUrl}}">

    </a>
    <a href="#/phones/{{phone.id}}">{{phone.name}}</a>
    <p>{{phone.snippet}}</p>
  </li>
</ul>
...

为每条记录添加图片,只需要使用ngSrc指令代替<img>的src属性标签就可以了。因为如果我们用一个正常src属性来进行绑定(<img class="diagram" src="{{phone.imageUrl}}">),浏览器会把AngularJS的{{ 表达式 }}标记直接进行字面解释,这时会发起一个向非法url:http://localhost:8000/app/{{phone.imageUrl}}的请求,因为浏览器载入页面时,同时也会请求载入图片。有了这个ngSrc指令,就会避免产生这种情况。

上面的应用只给我们的用户提供了一个简单的界面(一张所有手机的列表),并且所有的模板代码位于index.html文件中。

最后,我们增加一个能够显示我们列表中每一部手机详细信息的页面。

为了增加详细信息视图,我们可以拓展index.html来同时包含两个视图的模板代码,但是这样会很快给我们带来巨大的麻烦。相反,我们要把index.html模板转变成“布局模板”。这是我们应用所有视图的通用模板。其他的“局部布局模板”,根据当前的“路由”被填入,从而形成一个完整视图展示给用户。

AngularJS中的路由是通过$routeProvider来声明的,它是$route服务的提供者。这项服务使得控制器、视图模板与当前浏览器的URL可以轻易集成。它允许我们使用浏览器的历史(回退或者前进导航)和书签。

angular运行时,它会创建一个注入器,后面所有依赖注入的服务都会需要它。这个注入器自己并不知道$http$route是干什么的,注入器唯一的职责是载入指定的服务模块,在这些模块中注册所有定义的服务提供者,并且当需要时给一个指定的函数注入服务。这些服务通过它们的提供者“懒惰式”(需要时才加载)实例化。

提供者提供服务实例并且对外提供API接口的对象,它可以被用来控制一个服务的创建和运行。对于$route服务来说,$routeProvider对外提供了API接口,通过API接口允许你为你的应用程序定义路由规则。

为了给我们的应用配置路由,我们需要给应用创建一个模块。

angular.module('phonecat', []).
  config(['$routeProvider', function($routeProvider) {
    $routeProvider.
      when('/phones', {templateUrl: 'partials/phone-list.html', controller: PhoneListCtrl}).
      when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
      otherwise({redirectTo: '/phones'});
  }]);

我们把这个模块定义为phonecat,并且通过使用config方法,我们把$routeProvider注入到我们的配置函数中,并且使用$routeProvider.when方法来定义我们的路由规则。

我们的路由规则定义如下:

(1)当URL 映射段为/phones时,手机列表视图会被显示出来。为了构造这个视图,AngularJS会使用phone-list.html模板和PhoneListCtrl控制器。
(2)当URL 映射段为/phone/:phoneId时,手机详细信息视图被显示出来。这里:phoneId是URL的变量部分。为了构造手机详细视图,AngularJS会使用phone-detail.html模板和PhoneDetailCtrl控制器。

(3)otherwise({redirectTo: '/phones'})语句使得当浏览器地址不能匹配我们任何一个路由规则时,触发重定向到/phones。

我们重用之前创造过的PhoneListCtrl控制器,同时我们为手机详细视图添加一个新的PhoneDetailCtrl控制器。

为了让我们新创建的模块运行起来,我们需要在ngApp指令的值上指明模块的名字:

<!doctype html>
  <html lang="en" ng-app="phonecat">
    ...

  </html>

新的PhoneDetailCtrl控制器:

function PhoneDetailCtrl($scope, $routeParams) {
  $scope.phoneId = $routeParams.phoneId;
}

注意到在第二条路由声明中:phoneId参数的使用。所有以:符号声明的变量(此处变量为phones)都会被提取,然后存放在$routeParams对象中。

$route服务通常和ngView指令一起使用。ngView指令的角色是为当前路由把对应的视图模板载入到布局模板中。

<html lang="en" ng-app="phonecat">
  <head>
    ...
    <script src="lib/angular/angular.js"></script>
    ...
  </head>
  <body>

    <div ng-view>

    </div>

  </body>
</html>

注意,我们把index.html模板里面大部分代码移除,我们只放置了一个<div>容器,这个<div>具有ng-view属性。我们删除掉的代码现在被放置在phone-list.html模板中:

<div class="container-fluid">
<div class="row-fluid">
<div class="span2"> Search: <input ng-model="query">
Sort by:
<select ng-model="orderProp">
<option value="name">Alphabetical</option>
<option value="age">Newest</option>
</select> </div>
<div class="span10"> <ul class="phones">
<li ng-repeat="phone in phones | filter:query | orderBy:orderProp" class="thumbnail">
<a href="#/phones/{{phone.id}}" class="thumb"><img ng-src="{{phone.imageUrl}}"></a>
<a href="#/phones/{{phone.id}}">{{phone.name}}</a>
<p>{{phone.snippet}}</p>
</li>
</ul> </div>
</div>
</div>

同时我们为手机详细信息视图添加一个占位模板。

TBD: detail view for {{phoneId}}

大家注意到我们上面的两个模板中没有添加PhoneListCtrl或PhoneDetailCtrl控制器属性!

这样就实现了一个基于angular的多视图的应用程序。

加油!

AngularJS入门讲解3:$http服务和路由讲解的更多相关文章

  1. AngularJS路由系列(4)-- UI-Router的$state服务、路由事件、获取路由参数

    本系列探寻AngularJS的路由机制,在WebStorm下开发.主要包括: ● UI-Router的$state服务● UI-Router的路由事件● UI-Router获取路由参数 Angular ...

  2. 跟我学AngularJs:AngularJs入门及第一个实例

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:主要给大家介绍了AngularJs及其特性,并以3个实例来做说明. 本教程使用Angul ...

  3. 【转载】图灵AngularJS入门教程

    摘自图灵的AngularJS入门教程:http://www.ituring.com.cn/article/13471 感觉非常不错,所以推荐到首页一下! (一)Hello World! 开始学习Ang ...

  4. 《AngularJS入门与进阶》图书简介

    一.图书封面 二.图书CIP信息 图书在版编目(CIP)数据 AngularJS入门与进阶 / 江荣波著. – 北京 : 清华大学出版社, 2017 ISBN 978-7-302-46074-9 Ⅰ. ...

  5. AngularJS入门篇

    AngularJS是一个JavaScript框架,它通过指令扩展了HTML,且通过表达式绑定数据到 HTML.顺便一提,什么是框架?比如struts2.spring.hibernate.thinkph ...

  6. AngularJS入门心得4——漫谈指令scope

    上篇<AngularJS入门心得3——HTML的左右手指令>初步介绍了指令的概念和作用.已经和指令打过一个照面,就不会那么陌生了,今天主要介绍的是一个困扰了我很久终于想通的问题,这个问题与 ...

  7. Angularjs入门学习一 简介

    本系列文章是从头开始学习angularjs,下文中用ng表示angularjs,要知道从以为根深蒂固的jquery开发者转变开发思想,确实需要一段时间,下面介绍以下 angularjs,我也是参考网上 ...

  8. (一)Angularjs - 入门

    AngularJS进行应用开发的一个重要的思维模式: 从构造声明式界面入手 ng-app: 这个指定定义并且关联了使用angularJS的HTML页面部分 ng-model: 这个指定定义并绑定Ang ...

  9. Spring Cloud实战之初级入门(六)— 服务网关zuul

    目录 1.环境介绍 2.api网关服务 2.1 创建工程 2.3 api网关中使用token机制 2.4 测试 2.5 小结 3.一点点重要的事情 1.环境介绍 好了,不知不觉中我们已经来到了最后一篇 ...

随机推荐

  1. idea 插件

    https://plugins.jetbrains.com/plugin/4509-statistic

  2. java基础二(阅读Head First Java记录)

    写在前面的话 本部分是在语法基础上的一些内容,比如内部java函数库,继承多态等   “与”和“或”运算符 1.短运算符(&&,||)    &&与,必须表达式两边都为 ...

  3. oracle数据库在sys下直接修改用户密码

    首先用sys登录上去, 在命令窗口或者是能执行输入sql语句的地方输入下面代码, 回车就好 alter user you_username(要修改的用户名) identified by you_pas ...

  4. 寄存器CPU存储地址信息和数据信息的地方 CPU通过地址寄存器区分指令和数据

  5. Python id() 函数

    Python id() 函数  Python 内置函数 描述 id() 函数用于获取对象的内存地址. 语法 id 语法: id([object]) 参数说明: object -- 对象. 返回值 返回 ...

  6. IDEA07 快捷键统计插件之Key Promoter X

    1 官方介绍 该插件会统计你鼠标操作的次数,然后在一个窗口中展示出来 https://plugins.jetbrains.com/plugin/9792-key-promoter-x 2 下载.安装. ...

  7. sqlserver2008事物处理---待续

    声明事物:begin tran 回滚事物:ROLLBACK TRAN 提交事物:commit tran(不写会隐式提交) 判断是否发生异常: 结束前: IF @@ERROR <> 0 BE ...

  8. java高级工程师(一)

    一.无笔试题   不知道是不是职位原因还是没遇到,面试时,都不需要做笔试题,而是填张个人信息表格,或者直接面试     二.三大框架方面问题   1.Spring 事务的隔离性,并说说每个隔离性的区别 ...

  9. linux网络编程模型

    1.编程模型 Linux网络编程模型是基于socket的编程模型

  10. Composer安装和使用 - Windows

    记录windows下安装和使用Composer的方法 1,使用安装程序 这是将 Composer 安装在你机器上的最简单的方法. 下载并且运行 Composer-Setup.exe,它将安装最新版本的 ...