1 AngularJS服务
概念:
AngularJS中的服务指的是一些函数或者对象,它们可以在整个应用中持有某些行为和状态。
AngularJS的服务:
工厂类、服务和提供器
服务的功能:
不断的重复的行为、共享状态、缓存、工厂类等
2 页面迁移时的销毁与重建
HTML:
<!DOCTYPE html>
<html ng-app="notesApp">
<head>
<script type="text/javascript" src="../lib/angular.js"></script>
<script type="text/javascript" src="js/01_app.js"></script>
</head>
<body ng-controller="MainCtrl as mainCtrl">
<h1>Hello Controllers!</h1>
<button ng-click="mainCtrl.open('first')">Open First</button>
<button ng-click="mainCtrl.open('second')">Open Second</button>
<div ng-switch on="mainCtrl.tab">
<div ng-switch-when="first">
<div ng-controller="SubCtrl as ctrl">
<h3>First tab</h3>
<ul>
<li ng-repeat="item in ctrl.list">
<span ng-bind="item.label"></span>
</li>
</ul>
<button ng-click="ctrl.add()">Add More Items</button>
</div>
</div>
<div ng-switch-when="second">
<div ng-controller="SubCtrl as ctrl">
<h3>Second tab</h3>
<ul>
<li ng-repeat="item in ctrl.list">
<span ng-bind="item.label"></span>
</li>
</ul>
<button ng-click="ctrl.add()">Add More Items</button>
</div>
</div>
</div>
</body>
</html>
JS:
/** * Created by Relish on 2016/9/26. */
@H_301_306@var app = angular.module('notesApp',[]);
app.controller('MainCtrl',@H_301_306@function () {
@H_301_306@var @H_301_306@self = this;
@H_301_306@self.tab = 'first';
@H_301_306@self.open = @H_301_306@function (tab) {
@H_301_306@self.tab = tab;
};
});
app.controller('SubCtrl',@H_301_306@function () {
@H_301_306@var @H_301_306@self = this;
@H_301_306@self.tab = 'second';
@H_301_306@self.@H_301_306@list = [
{id: 1,label: 'Item 0'},{id: 2,label: 'Item 1'}
];
@H_301_306@self.add = @H_301_306@function () {
@H_301_306@self.@H_301_306@list.push({
id: @H_301_306@self.@H_301_306@list.length + 1,label: 'Item ' + @H_301_306@self.@H_301_306@list.length
});
};
});
销毁与重建的体现:
在First tab中添加li节点,切换至Second tab,再切换回First tab。之前添加的节点就消失了。显然,First tab页面被销毁并重建了。
原因:
一个控制器不能直接和另一个控制器进行交流并共享状态或者行为。
3 服务与控制器
@H_943_403@ @H_298_404@4 AngularJS中的依赖注入(Dependency Injection)
依赖注入的优点:
增强代码的重用性、模块化和可测试性。
4.1 对比
4.1.1 非依赖注入方式
@H_301_306@function fetchDashboardData(){
@H_301_306@var $http = @H_301_306@new HttpService();
@H_301_306@return $http.get('my/url');
}
4.1.2 依赖注入方式
@H_301_306@function fetchDashboardData($http){
@H_301_306@return $http.get('my/url');
}
5 举例($log)
<html ng-app="notesApp">
<body ng-controller="MainCtrl as mainCtrl">
<h1>Hello Services!</h1>
<button ng-click="mainCtrl.logStuff()">Log something</button>
<script src="../lib/angular.js"> </script>
<script type="text/javascript"> angular.module('notesApp',[]) .controller('MainCtrl',['$log',@H_301_306@function ($log) { @H_301_306@var self = @H_301_306@this; self.logStuff = @H_301_306@function () { $log.log('The button was pressed'); }; }]) </script>
</body>
</html>
安全的依赖注入:
上例中的依赖注入方式定义如下:
myModule.controller('MainCtrl',['$log',function ($log) {}])
也能这样定义
myModule.controller('MainCtrl',[function ($log) {}])
尽管第二种方式代码量更少更简洁,但是还是推荐使用第一种。原因是,当我们构建完应用宁部署时,通常会把JS最小化和不可读化(相当于Android的代码混淆)。经过这一步命名空间就失效了,$log会被修改称更短更无法让人识别的变量,从而导致代码出错。
6 注入顺序
一一对应
myModule.controller("MainCtrl",["$log","$window",function($l,$w){}])
7 判断何时使用服务
- 可重用性:不止一个控制器护着服务可能会用到它所实现的某个具体函数
- 应用级别的状态:需要在整个应用中保存状态(控制器在某些时候会销毁和重建)
- 与视图无关:实现的功能与视图无关
- 需要与第三方服务整合:服务更易于实现在单元测试中模拟或测试第三方服务
- 缓存/工厂类:需要缓存对象、使用工厂类创建模型对象时
8 创建简单的自定义AngularJS服务
HTML:
<html ng-app="notesApp">
<body ng-controller="MainCtrl as mainCtrl">
<h1>Hello Controllers!</h1>
<button ng-click="mainCtrl.open('first')">
Open First
</button>
<button ng-click="mainCtrl.open('second')">
Open Second
</button>
<div ng-switch on="mainCtrl.tab">
<div ng-switch-when="first">
<div ng-controller="SubCtrl as ctrl">
<h3>First tab</h3>
<ul>
<li ng-repeat="item in ctrl.list()">
<span ng-bind="item.label"></span>
</li>
</ul>
<button ng-click="ctrl.add()">
Add More Items
</button>
</div>
</div>
<div ng-switch-when="second">
<div ng-controller="SubCtrl as ctrl">
<h3>Second tab</h3>
<ul>
<li ng-repeat="item in ctrl.list()">
<span ng-bind="item.label"></span>
</li>
</ul>
<button ng-click="ctrl.add()">
Add More Items
</button>
</div>
</div>
</div>
<script src="../lib/angular.js"> </script>
<script src="js/03_app.js"></script>
</body>
</html>
JS:
/** * Created by Relish on 2016/9/26. */
angular.module('notesApp',[])
.controller('MainCtrl',[@H_301_306@function () {
@H_301_306@var @H_301_306@self = this;
@H_301_306@self.tab = 'first';
@H_301_306@self.open = @H_301_306@function (tab) {
@H_301_306@self.tab = tab;
};
}])
.controller('SubCtrl',['ItemService',@H_301_306@function (ItemService) {
@H_301_306@var @H_301_306@self = this;
@H_301_306@self.@H_301_306@list = @H_301_306@function () {
@H_301_306@return ItemService.@H_301_306@list();
};
@H_301_306@self.add = @H_301_306@function () {
ItemService.add({
id: @H_301_306@self.@H_301_306@list().length + 1,label: 'Item ' + @H_301_306@self.@H_301_306@list().length
});
};
}])
//通过angular.moudle.factory创建服务。
.factory('ItemService',[@H_301_306@function () {
@H_301_306@var items = [
{id: 1,label: 'Item 1'}
];
@H_301_306@return {
@H_301_306@list: @H_301_306@function () {
@H_301_306@return items;
},add: @H_301_306@function (item) {
items.push(item);
}
};
}]);