【AngularJS: Up & Running】第05章_AngularJS服务揭秘

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.
 */
var app = angular.module('notesApp', []);
app.controller('MainCtrl', function () {
    var self = this;
    self.tab = 'first';
    self.open = function (tab) {
        self.tab = tab;
    };
});

app.controller('SubCtrl', function () {
    var self = this;
    self.tab = 'second';
    self.list = [
        {id: 1, label: 'Item 0'},
        {id: 2, label: 'Item 1'}
    ];
    self.add = function () {
        self.list.push({
            id: self.list.length + 1,
            label: 'Item ' + self.list.length
        });
    };
});

销毁与重建的体现
在First tab中添加li节点,切换至Second tab,再切换回First tab。之前添加的节点就消失了。显然,First tab页面被销毁并重建了。
原因

一个控制器不能直接和另一个控制器进行交流并共享状态或者行为。

3 服务与控制器

服务器控制器
业务层逻辑表现层逻辑
独立于页面和视图直接相关
驱动应用驱动UI
可重用的一次性的
决定如何调用服务端接口,常见的验证逻辑,应用级别的数据存储,可重用的业务逻辑决定如何获取数据,显示哪些数据,如何进行用户交互,展示UI样式

4 AngularJS中的依赖注入(Dependency Injection)

依赖注入的优点:

增强代码的重用性、模块化和可测试性。

4.1 对比

4.1.1 非依赖注入方式

function fetchDashboardData(){
    var $http = new HttpService();
    return $http.get('my/url');
}

4.1.2 依赖注入方式

function fetchDashboardData($http){
    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', function ($log) {
                var self = this;
                self.logStuff = 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){}])
l log; w window。

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', [function () {
        var self = this;
        self.tab = 'first';
        self.open = function (tab) {
            self.tab = tab;
        };
    }])
    .controller('SubCtrl', ['ItemService',
        function (ItemService) {
            var self = this;
            self.list = function () {
                return ItemService.list();
            };
            self.add = function () {
                ItemService.add({
                    id: self.list().length + 1,
                    label: 'Item ' + self.list().length
                });
            };
        }])
        //通过angular.moudle.factory创建服务。
    .factory('ItemService', [function () {
        var items = [
            {id: 1, label: 'Item 0'},
            {id: 2, label: 'Item 1'}
        ];
        return {
            list: function () {
                return items;
            },
            add: function (item) {
                items.push(item);
            }
        };
    }]);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值