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>¥ </span>{{obj.price | number:2}}</td> 68 <td>{{obj.count | number:0}}</td> 69 <td><span>¥ </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>¥ </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 }]);

浙公网安备 33010602011771号