angularjs应用骨架(3)

  好,继续上一章节我们继续聊聊angularjs骨架。开发任何一款优秀的应用都会面临一项非常困难的工作,那就是找到一种合适的方式方法把代码组织在合适的功能范围内。我们已经看过控制器的处理方式,它会提供一块空间,把正确的数据模型和函数暴露给视图模版。但是用来支持我们应用的代码该怎么办呢?有一块最明显的可以放在这些代码的地方,那就是控制器的函数。

  这种做法对于小型的应用和例子来说可以工作的很好,我们已经看到过很多这样的例子,但是在真实的应用中,这种做法很快就会使得代码无法维护。控制器将会变成一个垃圾场,我们做的所有东西都会倒在里面。它们会变得非常难以理解,并且很难修改。

  我们来看模块

  我们来看模块,它们提供了一种方法,可以用来组织应用中一块功能区域的依赖关系;同时还提供了一种机制,可以自动解析依赖关系(又叫做依赖注入)。一般来说,我们把这些东西叫做依赖服务。因为它们负责为应用提供特殊服务。

  例如,我们要在购物站点中的一个控制器中需要从服务器上获取一个商品列表,那么我们就需要这些对象——不妨把它叫做Items——用来处理服务器端获取商品列表的工作,进而,Items对象就需要以某种方式与服务器上的数据库进行交互,可以通过XHR或者WebSocket。

  如果没有模块的情况下,我们的控制器看起来可能就是这样:

  

1  function ItemsViewController(){
2         //向服务器发起请求
3
4         //解析响应并放入Items对象
5
6         //把Items数组放到$scope上,这样视图才能显示它
7     }

  虽然这样可以运行,但是却存在大量潜在的问题:

  1、如果其他控制器也要从服务器上获取Items,那么只能把这段代码再写一遍,这会给维护工作带来很大的负担。

  2、加上一些其他因素,例如服务端认证、解析数据的复杂性,会使得控制器对象很难划分出一个合理的功能边界,并且代码阅读起来非常困难。

  3、使得单元测试变得复杂。

  利用模块和模块内置的依赖注入的功能,就可以把控制器变得简单,示例如下:

  

1 app.controller(‘myController‘, function ($scope,Items) {
2        $scope.items =Items.query();
3         ……
4 }

   你可能会问,“不错,看起来还不错,但是Items是什么东西,从哪里来?”以上代码,假如我们已经把Items变成了一个服务。服务都是单例的对象,它们用来执行必要的任务支撑应用的功能。

  Angular内置了很多服务,例如$location服务,用来和浏览器的地址栏进行交互;$route服务,用来根据URL地址的变化切换视图;还有$http服务,用来和服务器进行交互。你也可已创建自己的服务,用它们来实现你的应用所特有的功能,如果需要,服务可以在任何控制器中共享,当你需要多个控制器之间进行交互和共享状态时这些服务就是一种很好的机制。Angular的内置服务一$开头,你当然可以为你的服务随意起名字,但是最好不要以$开头,以免引起命名冲突。你可以使用模型对象的API来定义服务。一下三种函数可以用来创建一般的服务,它们的复杂度和功能度不同。

  函数1:provider(name,Object or constructor()),定义:一个可配置的服务,创建的逻辑比较复杂。

  函数2:factory(name,$getFunction() ),定义:一个不可配置的服务,创建逻辑比较复杂。可以把它看成provider(name,{$get:$getFunction()})。

  函数3:servive(name,conttuctor()),定义:一个不可配置的服务,创建逻辑比较简单。

  我们先来看一个使用factory创建服务的例子。我们可以像下面这样来编写服务:

  

 1 var app = angular.module(‘MyApp‘, []);
 2 app.factory(‘Items‘, function () {
 3     var items={};
 4     items.query= function () {
 5         return [
 6             {title: "羽毛球", quantity: 8, price: 3.99},
 7             {title: "篮球", quantity: 17, price: 1.99},
 8             {title: "足球", quantity: 5, price: 3.99}
 9         ];
10     };
11     return items;
12 });

  为了能让这一机制能够和模版配合起来,我们把模版名称告诉ng-app指令。  

  完整代码如下:

  

 1 <!DOCTYPE html>
 2 <html ng-app="MyApp">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title></title>
 6     <script src="static/js/angular.js" type="text/javascript"></script>
 7     <script src="static/app/controller/shopingcartcontroller.js" type="text/javascript"></script>
 8 </head>
 9 <body ng-controller="myController">
10     <div>
11         <h1>Your Shoping Cart</h1>
12         <div ng-repeat="item in items">
13             <span>{{item.title}}</span>
14             <input type="text" ng-model="item.quantity"/>
15             <span>{{item.quantity | currency}}</span>
16             <span>{{item.quantity * item.price | currency}}</span>
17             <button ng-click="remove($index)">remove</button>
18         </div>
19
20         <div>total:{{bill.totalCart| currency}}</div>
21         <div>Discount:{{bill.discount | currency}}</div>
22         <div>Subtotal:{{ bill.subtotal | currency}}</div>
23     </div>
24 </body>
25 </html>

 1 /**
 2  * Created by Administrator on 2015/6/12.
 3  */
 4 var app = angular.module(‘MyApp‘, []);
 5 app.factory(‘Items‘, function () {
 6     var items={};
 7     items.query= function () {
 8         return [
 9             {title: "羽毛球", quantity: 8, price: 3.99},
10             {title: "篮球", quantity: 17, price: 1.99},
11             {title: "足球", quantity: 5, price: 3.99}
12         ];
13     };
14     return items;
15 });
16 app.controller(‘myController‘, function ($scope,Items) {
17     $scope.bill = {};
18     $scope.items =Items.query();
19
20     $scope.remove = function (index) {
21         $scope.items.splice(index, 1);
22     }
23
24     //var calulateTotal = function () {
25     //    var total = 0;
26     //    for (var i = 0, len = $scope.items.length; i < len; i++) {
27     //        total = total + $scope.items[i].price * $scope.items[i].quantity;
28     //    }
29     //    $scope.bill.totalCart = total;
30     //    $scope.bill.discount = total > 100 ? 10 : 0;
31     //    $scope.bill.subtotal=total - $scope.bill.discount;
32     //};
33
34     $scope.$watch(function () {
35         var total = 0;
36         for (var i = 0, len = $scope.items.length; i < len; i++) {
37             total = total + $scope.items[i].price * $scope.items[i].quantity;
38         }
39         $scope.bill.totalCart = total;
40         $scope.bill.discount = total > 100 ? 10 : 0;
41         $scope.bill.subtotal=total - $scope.bill.discount;
42     });
43
44
45
46
47     function ItemsViewController(){
48         //向服务器发起请求
49
50         //解析响应并放入Items对象
51
52         //把Items数组放到$scope上,这样视图才能显示它
53     }
54 });

  

  当然你如果你需要使用第三个方包中的所提供的服务或指令,它们一般会有自己的模块,所以需要在应用中定义依赖关系才能应用它们。假如你引入了模块A和B,那么应用中 的模块声明看起来可能会像下面这样:

  var appMod=agular.module(‘myapp‘,[‘A‘,‘B‘]);

  

  使用过滤器格式化数据

  你可以使用过滤器来声明如何变换数据显示的格式,然后在展示给用户,你只要在模版中使用一个插值变量即可。使用过滤器的语法是:

  {{expression | filterName : parameter1 : parameter2}}

  过滤器中的多个参数使用冒号隔开。

  Angular中有很多过滤器,如currency

  {{12.9 | currency}}

  以上代码得到结果就是$12.90

  在绑定过程中使用管道符号把过滤器连接起来。例如:

  {{12.9 | currency | number}}

  得到的结果是$13

  当然,你也不必受限与内置过滤器,你也可以自定义过滤器:

  

1   <p> {{ ‘my name is amber.xu‘ | titleCase }}</p>

 1 app.filter(‘titleCase‘, function () {
 2     var titleCaseFilter= function (input) {
 3         var words=input.split(‘ ‘);
 4         for(var i=0;i<words.length;i++){
 5             words[i]=words[i].charAt(0).toUpperCase() + words[i].slice(1);
 6         }
 7         return words.join(‘ ‘);
 8     };
 9     return titleCaseFilter;
10 });

效果如下:

  My Name Is Amber.xu

  

  使用路由和$location切换视图

  虽然从技术上来说AJAX应用确实是单页应用,但是在很多时候,出于各种原因,我们需要为用户展示或隐藏一些子页面视图。

  我们可以利用angular的$route服务来管理这种场景,可以利用路由服务来定义这样一种东西:对于浏览器的一种url,angular将会加载一中视图模版,并实例化一个控制器为模版提供内容。在应用中你可以使用$routeProvider服务上的函数来创建路由,把需要创建的路由当成一个配置块来传给函数即可。创建过程类似一下的伪代码:

  

1 app.config(function ($routeProvider) {
2     $routeProvider.when(‘url‘,{controller:aController,templateUrl:‘/path/to/template‘}).
3         when(...other mapping for your app...).
4         ...
5         otherwise(...waht to do  if nothing else matches...)
6 });

  以上代码是说,当浏览器中的URL发生变成指定的取值时,angular将会加载/path/to/template路径下的模版,然后把模版中的跟元素关联到aController上(因为我们在模版中写了ng-controller=aController)最后一行的otherwise相当于else或者default。

  待续……

时间: 2024-12-22 21:45:04

angularjs应用骨架(3)的相关文章

用angularjs开发下一代web应用(二):angularjs应用骨架(一)

1.调用angularjs 1>加载angularjs库 可以从google的CDN(内容分发网络)中加载,获取快,并且可以在多个应用之间缓存脚本库(建议使用这种方式,但是中国的特殊国情,不能用这种方式): <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js"></script> 本地主机方式. 2>使用ng-app申明angular的边界

用angularjs开发下一代web应用(二):angularjs应用骨架(二)

1.浅谈非入侵式JavaScript <div ng-click="doSomething()">...</div>这些指令和原来的事件处理器有以下不同之处: 在所有浏览器中具有相同的行为.Angular将会帮你屏蔽差异性. 不会在全局命名空间中进行操作.你所指定的表达式只能访问元素控制器作用域范围内的函数和数据. 2.列表.表格以及其他迭代型元素         ng-repeat可能是最有用的Angular指令了,它可以根据集合中的项目一次创建一组元素的多份

angularjs应用骨架(2)

时隔一个星期,接着上一篇的angularjs应用骨架继续聊聊angularjs其他的其他的内容. 区分UI和控制器的职责 在应用控制器中有三种职责: 1.为应用中模型设置初始状态 2.通过$scope对象把数据模型和函数暴露给视图(UI模版) 3.监视模型其余部分的变化,并采取相应的动作 我这主要想说的是第三项的功能:为了让控制器保持小巧可控制的状态,我们的建议是,为视图中的每一块功能区域创建一个控制器.就是说如果你有一个菜单,就创建一个MenuController,如果你有一个面包屑导航就创建

angularjs应用骨架

使用典型的类库时,你可以选择并使用你所喜欢的功能:而对于angularjs框架来说,必须把它看成一个完成度套件来使用,框架中的所有的东西都包含在里面,接下来将会介绍angular的基础模块,这样你就可以理解它们是如何被装配在一起的. 调用Angular 为了使用angular,所有的引用都必须做两件事情: 1.加载angular库. 2.使用ng-app指令告诉angular应该管理DOM中的那一部分. 加载脚本 加载类库的操作非常简单,与其他javascript类库遵循同样的规则. 使用ng-

angularjs应用骨架(4)

继续上一篇 继续了解angular其他内容. 与服务器交互 真正的应用需要和真实的服务器进行交互移动应用和新兴的Chrome桌面应用可能是例外.但是对于此外的所有应用来说,无论是想把数据持久化到云端还是需要其他用户进行实时交互,都需要让应用与服务器进行交互. 为了实现这一点,angular提供了一种叫做$http的服务,它提供了一个可扩展的抽象方法列表,使得与服务器的交互更加容易.它支持HTTP.JSONP和CORS方式,它还包含了安全性支持,避免了JSON格式的脆弱性和跨站请求伪造(XSRF)

用AngularJS开发下一代Web应用 系列入门基础教程

开篇介绍 AngularJS是什么东西?我觉得不用再描述了.可自行去充电一下.按照惯例,让我们先看看一个Hello World的开门简介吧. <!doctype html> <html ng-app> <head> <script src="http://code.angularjs.org/angular-1.0.1.min.js"></script> </head> <body> Your name

AngularJs 基础(60分钟入门)

AngularJs是一个不错的用于开发SPA应用(单页Web应用)的框架.单页Web应用(single page web application,SPA),就是只有一张Web页面的应用.浏览器一开始会加载必需的HTML.CSS和JavaScript,所有的操作都在这张页面上完成,由JavaScript来控制不同view在这个页面上的呈现.本文源于Youtube上一个不错的AngularJs的入门教程视频:AngularJS Fundamentals In 60-ish Minutes,主要讲解了

AngularJs 基础(60分钟入门) (转)

AngularJs是一个不错的用于开发SPA应用(单页Web应用)的框架.单页Web应用(single page web application,SPA),就是只有一张Web页面的应用.浏览器一开始会加载必需的HTML.CSS和JavaScript,所有的操作都在这张页面上完成,由JavaScript来控制不同view在这个页面上的呈现.本文源于Youtube上一个不错的AngularJs的入门教程视频:AngularJS Fundamentals In 60-ish Minutes,主要讲解了

AngularJS 中文资料+工具+库+Demo 大搜集

中文学习资料: 中文资料且成系统的就这么多,优酷上有个中文视频. http://www.cnblogs.com/lcllao/archive/2012/10/18/2728787.html   翻译的官方的Guide http://www.ituring.com.cn/minibook/303  翻译的官方的tutorial http://www.lovelucy.info/angularjs-best-practices.html  Angular最佳实践 http://zouyesheng.