angularJs 内置的服务 自定义服务 依赖注入 注入器

一、ng内置的服务($http,$interval,$timeout...)

①双向数据绑定的工作原理
<p>{{num}}</p>===>ng框架自动添加一个监听(watch),和$scope.$watch是一样的,只要是数据发生了变化,视图就会更新。???
如何知道数据是否发生了变化?
ng会周期性的运行一个函数来检查$scope的模型数据是否发生变化,称之为$digest===>$scope.$digest()

什么时候才会调用$digest()?
ng指令,很少直接手工调用$digest(),都是$scope.$apply();==>$rootScope.$digest()

setInterval是原生js的功能,本身就是一个循环,需要我们手工调用$scope.

②$interval $timeout

var t = $interval(function(){},100);
$timeout(function(){},100);

$interval.cancel(t);

定时器练习:
使用周期性定时器来实现一个图片轮播,同时实现一个自增的计数器,当计数器大于30时自动停止。

 1 <!DOCTYPE html>
 2 <html ng-app="myModule">
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <script src="js/angular.js"></script>
 6     <title></title>
 7 </head>
 8 <body>
 9 <div ng-controller="myCtrl">
10     <p><img ng-src="img/{{imglist[number]}}" alt=""/></p>
11     <p>{{count}}</p>
12 </div>
13 <script>
14     var app = angular.module('myModule', ['ng']);
15     app.controller('myCtrl', function ($scope,$interval) {
16         $scope.imglist = ['1.jpg','2.jpg','3.jpg','4.jpg'];
17         $scope.number = 0;
18         $scope.count = 0;
19         var timer = $interval(function(){
20             $scope.number++;
21             $scope.count++;
22             if($scope.number > 3){
23                 $scope.number=0;
24             }
25             if($scope.count >= 30){
26                 $interval.cancel(timer);
27             }
28         },200);
29 
30     });
31 </script>
32 </body>
33 </html>

 

③$http
AJAX调用:$http服务向服务器发起AJAX请求,异步的获取服务器端返回的数据,声明为模型数据,在视图中展现出来。

$http.get('url').success(function(data){....});
$http.post('url',data).success(function(data){..})

如果要发起post请求,必须设置头信息,设置的方式:
$http.defaults.headers.post = {'Content-Type':'application/x-www-form-urlencoded'};


练习:$http发起get请求,编写一个php文件,返回json数组。
显示在table中。
分析:apache服务跑起来,将工程放在c:\xampp\htdocs的目录中。
第一步:编写php文件,在浏览器中去访问该文件能否拿到数据
第二步:$http发起get请求,拿到数据
第三步:将数据显示在table中。

HTML文件如下

 1 <!DOCTYPE html>
 2 <html ng-app="myModule">
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <script src="js/angular.js"></script>
 6     <title></title>
 7 </head>
 8 <body>
 9 <div ng-controller="myCtrl">
10     <table>
11         <thead>
12         <tr>
13             <th>姓名</th>
14             <th>年龄</th>
15         </tr>
16         <tbody>
17         <tr ng-repeat="obj in list">
18             <td ng-repeat="value in obj">{{value}}</td>
19         </tr>
20         </tbody>
21         </thead>
22     </table>
23 </div>
24 <script>
25     var app = angular.module('myModule', ['ng']);
26     app.controller('myCtrl', function ($scope,$http) {
27         $http.get('data/data1.php')
28                 .success(function(data){
29             console.log(data);
30             $scope.list = data;
31         });
32     });
33 </script>
34 </body>
35 </html>

php代码如下:

 

 1 <?php
 2     header("content-Type:application/json");
 3     $dataList = [
 4     ['name' => 'Tom','age' => '18','score' => '55'],
 5     ['name' => 'Dom','age' => '14','score' => '88'],
 6     ['name' => 'Gom','age' => '18','score' => '75'],
 7     ['name' => 'Hom','age' => '12','score' => '45'],
 8     ['name' => 'Kom','age' => '16','score' => '96']
 9     ];
10     echo json_encode($dataList);
11 ?>

 

 


二、自定义服务

无论是哪种方式创建的服务,和ng内置的服务使用的方式都是一致:注入进来,直接拿来用

1、factory方法

app.factory('服务名称',function(){
return {
}
})

 1 <!DOCTYPE html>
 2 <html ng-app="myModule">
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <script src="js/angular.js"></script>
 6     <title></title>
 7 </head>
 8 <body>
 9 <div ng-controller="myCtrl">
10     <button ng-click="shows()">Clickme</button>
11 </div>
12 <script>
13     var app = angular.module('myModule', ['ng']);
14     //通过factory创建服务
15     app.factory('$show',function(){
16         return {
17             showFunction:function(){
18                 alert('hello serverse');
19             }
20         }
21     });
22     app.controller('myCtrl', function ($scope,$show) {
23         $scope.shows=function(){
24             $show.showFunction();
25         }
26     });
27 </script>
28 </body>
29 </html>

 

2、service方法

app.service('服务名称',function(){

})

 1 <!DOCTYPE html>
 2 <html ng-app="myModule">
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <script src="js/angular.js"></script>
 6     <title></title>
 7 </head>
 8 <body>
 9 <div ng-controller="myCtrl">
10     <p><button ng-click="fun1()">启动</button></p>
11     <p><button ng-click="fun2()">停止</button></p>
12 </div>
13 <script>
14     var app = angular.module('myModule', ['ng']);
15     app.service('$qwer',function($interval){
16         this.function1 = function(){
17             t1 = $interval(function(){
18                 console.log("呼啦啦...");
19             },200);
20         }
21         this.function2 = function(){
22             $interval.cancel(t1);
23         }
24     });
25     app.controller('myCtrl', function ($scope,$qwer) {
26         $scope.fun1 = function(){
27             $qwer.function1();
28         }
29         $scope.fun2 = function() {
30             $qwer.function2();
31         }
32     });
33 </script>
34 </body>
35 </html>

 

3、constant、value
创建的服务返回是变量
app.constant('服务名称',value) ==> 创建配置数据
app.value('服务名称',value) ==》创建对象

常量服务如果注入到控制器之后,可以通过angular.extend方法进行重置

 1 <!DOCTYPE html>
 2 <html ng-app="myApp">
 3 <head lang="en">
 4   <meta charset="UTF-8">
 5   <script src="js/angular.js"></script>
 6   <title></title>
 7 </head>
 8 <body>
 9 
10 <div ng-controller="myCtrl">
11   <p>{{id}}</p>
12   <p>{{price}}</p>
13 
14   <button ng-click="reset()">reset</button>
15 </div>
16 
17 <script>
18   var app = angular.module('myApp', ['ng']);
19 
20 //  使用constant创建服务
21   app.constant('$ID',{id:10});
22 
23 //  使用value创建服务
24   app.value('$price',{price:30});
25 
26   app.controller('myCtrl',
27     function ($scope,$ID,$price) {
28       $scope.id = $ID.id
29       $scope.price = $price.price;
30 
31       $scope.reset = function () {
32 
33         angular.extend($ID,{id:20});
34         angular.extend($price,{price:33});
35 
36         $scope.id = $ID.id
37         $scope.price = $price.price;
38       }
39   })
40 
41 </script>
42 
43 </body>
44 </html>


三、依赖注入

1、文件压缩
使用YUICompresspor来完成文件的压缩,使用方式有2种:
①直接通过命令行

②借助webStorm来配置
File--》Settings-->tools-->file watchers--》点击右上角的+号--》选中YUICOMPRESSOR-JS,设置program为jar包。

文件压缩的作用:
①删除所有的注释
②删除空白、没有语义的字符
③简化变量名、函数名、形参名--》混淆

2、依赖注入
每个angularjs的应用,注入器负责查找和创建依赖的服务,注入器的本质是服务的定位器,快速定位到应用需要注入的各种服务,在定位服务的过程当中,需要提供注入的标记,根据标记的不同,划分为3大类:
①推断式依赖注入(猜测)
这种方法不需要关心注入服务的顺序,ng会自动处理,根据参数列表注入服务,如果参数一旦经过混淆或者压缩,有问题。

只能处理原始的代码

②标记式依赖注入
直接调用$inject属性来完成标记式的注入声明,该属性是一个字符型的数组,由于它是数组,所以有引入的先后顺序的。

③行内式依赖注入(内联)
在构建一个ng对象时,允许开发人员将一个字符型数组作为对象的参数,而不仅仅是一个函数;在这个数组中,除最后一个元素必须是函数体外,其余都是注入的服务名称,而且顺序保持一致。

建议:使用第三种依赖注入的方式:行内式依赖注入。

练习:要求采用行内式依赖注入,创建一个服务,服务中有一个方法实现求和 add:function(arg1,arg2)
视图:两个input标签,一个按钮(调用服务的add方法将求和的结果弹窗显示出来)。

HTML代码如下:

 1 <!DOCTYPE html>
 2 <html ng-app="myModule">
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <script src="js/angular.js"></script>
 6     <script src="js/line_inject.min.js"></script>
 7     <title></title>
 8 </head>
 9 <body>
10     <div ng-controller="myCtrl">
11         <p>
12             <label for="arg1">请输入第一个数:</label>
13             <input type="number" id="arg1" ng-model="num1"/>
14         </p>
15         <p>
16             <label for="arg2">请输入第二个数:</label>
17             <input type="number" id="arg2" ng-model="num2"/>
18         </p>
19         <p>
20             <button ng-click="addNum()">求和 </button>
21             <b> {{result}}</b>
22         </p>
23     </div>
24 </body>
25 </html>

JavaScript代码如下:

 1 /**
 2  * Created by xly on 2016/12/28.
 3  */
 4 var app = angular.module('myModule',['ng']);
 5 app.service('$add',function(){
 6     this.addFunction = function(arg1,arg2){
 7         return arg1 + arg2;
 8     }
 9 })
10 app.controller('myCtrl',['$scope','$add',function($scope,$add){
11     $scope.addNum = function(){
12        $scope.result = $add.addFunction($scope.num1,$scope.num2);
13         //alert($scope.result);
14     }
15 }]);

 


3、注入器($injector)

定位和查找服务的。

has --》查找服务是否存在
get --》得到服务的实例

练习:在案例基础之上,放置一个按钮,点击按钮时,通过get拿到实例并调用print方法(angular.injector-->$injector 行内式依赖注入)

HTML代码如下:

 1 <!DOCTYPE html>
 2 <html ng-app="myModule">
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <script src="js/angular.js"></script>
 6     <script src="js/line_inject_injector.min.js"></script>
 7     <title></title>
 8 </head>
 9 <body>
10     <div ng-controller="myCtrl">
11         <p>
12             <label for="arg1">请输入第一个数:</label>
13             <input type="number" id="arg1" ng-model="num1"/>
14         </p>
15         <p>
16             <label for="arg2">请输入第二个数:</label>
17             <input type="number" id="arg2" ng-model="num2"/>
18         </p>
19         <p>
20             <button ng-click="addNum()">求和 </button>
21             <b> {{result}}</b>
22         </p>
23     </div>
24 </body>
25 </html>

JavaScript 代码如下:

 1 /**
 2  * Created by xly on 2016/12/28.
 3  */
 4 var app = angular.module('myModule',['ng']);
 5 app.service('$add',function(){
 6     this.addFunction = function(arg1,arg2){
 7         return arg1 + arg2;
 8     }
 9 })
10 //行内inject注入
11     app.controller('myCtrl',['$scope','$injector',function($scope,$injector){
12     var injector = angular.injector(['ng','myModule']);//得到模块列表
13     var addExists = injector.has('$add');//判断模块列表是否存在服务
14     if(addExists){
15         var add = injector.get('$add');//得到服务
16         }
17     $scope.addNum = function(){
18        $scope.result = add.addFunction($scope.num1,$scope.num2);
19         //alert($scope.result);
20     }
21 }]);

 

实现一个购物车:要求从php服务器获取初始化的数据,通过$http.

HTML 代码如下:

 1 <!DOCTYPE html>
 2 <html ng-app="myModule">
 3 <head lang="en">
 4     <meta charset="UTF-8">
 5     <script src="js/angular.js"></script>
 6     <script src="js/homework_shopCart.min.js"></script>
 7     <title></title>
 8     <style>
 9         #box{
10             width:80%;
11             margin:0 auto;
12         }
13         #left{
14             float: left;
15         }
16         table{
17             width:70%;
18             margin:0 auto;
19             float: right;
20             margin-top:-60px;
21             border-collapse: collapse;
22         }
23         table tr,td,th{
24             text-align: center;
25             border:1px solid #ddd;
26         }
27         #addbtn{
28             width:100px;
29         }
30         td span{
31             color:#e4393c;
32             font-weight:bold;
33             font-size:20px;
34         }
35         tr td:nth-child(1),td:nth-child(3){
36             padding-left: 35px;
37             text-align:left;
38         }
39     </style>
40 </head>
41 <body>
42     <div ng-controller="myCtrl" id="box">
43         <p id="addbtn"><button ng-click="isShows()">添加</button></p>
44         <div ng-show="isShow" id="left">
45             <p>
46                 <label for="price">单价</label>
47                 <input type="text" id="price" placeholder="请输入单价"  ng-model="price"/>
48             </p>
49             <p>
50                 <label for="count">单价</label>
51                 <input type="text" id="count" placeholder="请输入数量"  ng-model="count"/>
52             </p>
53             <p><input type="button" value="确定" ng-click="addProduct()"/></p>
54         </div>
55         <table>
56             <caption><h3>购物车详情</h3></caption>
57             <thead>
58             <tr>
59                 <th>单价</th>
60                 <th>数量</th>
61                 <th>小计</th>
62                 <th>删除</th>
63             </tr>
64             </thead>
65             <tbody>
66             <tr ng-repeat="obj in shopData">
67                 <td><span>&yen; </span>{{obj.price | number:2}}</td>
68                 <td>{{obj.count | number:0}}</td>
69                 <td><span>&yen; </span>{{obj.price*obj.count | number:2}}</td>
70                 <td><button ng-click="deleteShop()">删除</button></td>
71             </tr>
72             </tbody>
73            <tfoot>
74            <tr>
75                <td><b>总计</b></td>
76                <td colspan="3"><span>&yen; </span>{{sumcount() | number:2}}</td>
77            </tr>
78            </tfoot>
79         </table>
80 
81     </div>
82 </body>
83 </html>

 

JavaScript 代码如下:

 

 1 /**
 2  * Created by xly on 2016/12/28.
 3  */
 4 var app = angular.module('myModule',['ng']);
 5 app.controller('myCtrl',['$scope','$http',function($scope,$http){
 6     $http.get('data/homework.php')
 7         .success(function(data){
 8             $scope.shopData = data;
 9         });
10     $scope.isShow = true;
11     $scope.isShows = function(){
12         if($scope.isShow){
13             $scope.isShow = false;
14         }else{
15             $scope.isShow = true;
16         }
17     }
18     $scope.sumcount = function(){
19         var totolprice = 0;
20         angular.forEach($scope.shopData,function(value,key){
21             var pr = parseFloat(value.price);
22             var cot= parseFloat(value.count);
23             var counts = pr * cot
24             totolprice += counts;
25         })
26         console.log(totolprice);
27         return totolprice;
28     }
29     $scope.addProduct = function(){
30         $scope.p = $scope.price;
31         $scope.c = $scope.count;
32         if($scope.p !== undefined && $scope.c !== undefined){
33             $scope.shopData.push(
34                 {'price':$scope.p,'count':$scope.c}
35             );
36             alert('添加信息成功!!!');
37         }else{
38             $scope.isShow = false;
39             alert('单价 或 数量 不能为空!!!');
40         }
41     }
42     $scope.deleteShop = function(){
43         console.log(this.$index);
44         $scope.shopData.splice(this.$index,1);
45         console.log($scope.shopData);
46     }
47 }]);

 

posted @ 2016-12-29 13:45  时间脱臼  阅读(264)  评论(0)    收藏  举报