zoukankan      html  css  js  c++  java
  • 模块与服务的协作

    AngularJS模块定义了三个方法用于定义服务:factory、service、provider.

    一、使用factory方法

    创建服务最简单的方法就是使用module.factory方法,传入服务名称和factory函数作为参数并返回服务对象。通过工厂函数返回的对象是服务对象,工厂函数仅被调用一次,因为该对象创建和返回时使用的服务在应用程序中是必不可少的。

    Note: 当心别重复使用服务名称,如果你这样做了,已存在的服务将被覆盖。

    <body ng-controller="defaultCtrl">
        <div class="well">
            <div class="btn-group" tri-button
                 counter="data.totalClicks" source="data.cities">
                <button class="btn btn-default"
                        ng-repeat="city in data.cities">
                    {{city}}
                </button>
            </div>
            <h5>Total Clicks: {{data.totalClicks}}</h5>
        </div>
    </body>
    angular.module("exampleApp", ["customDirectives", "customServices"])
            .controller("defaultCtrl", function ($scope, logService) {
                $scope.data = {
                    cities: ["London", "New York", "Paris"],
                    totalClicks: 0
                };
    
                $scope.$watch('data.totalClicks', function (newVal) {
                    logService.log("Total click count: " + newVal);
                });
            });
    angular.module("customServices",[])
        .factory("logService",function(){
           var messageCount=0;
           return{
               log:function(msg){
                    console.log("(LOG+"+messageCount+++")"+msg);
               } 
            } 
        })    
    // service中我在工厂函数里定义的messageCount变量,而不是作为服务对象的一部分。因为不想让服务的调用者能够修改该计数器,而放在服务对象的外面则意味着它无法被调用者使用。
    angular.module("customDirectives",["customServices"])
        .directive("triButton",function(logService){
            return{
                scope:{counter:"=counter"},
                link:function(scope,element,attrs){
                    element.on("click",function(event){
                        logService.log("Button click:"+event.target.innerText);
                        scope.$apply(function(){
                            scope.counter++;
                         });
                    })
                }
            }
    })    

    运行结果证明了服务是单例对象:

    (LOG+0) Total click count:0

    (LOG+1) Button click:London

    (LOG+2) Total click count:1

    (LOG+3) Button click:New York

    二、使用service方法

    使用module.service方法也可以创建服务对象,但其中稍有不同。当AngularJS需满足由factory方法定义的服务的依赖关系时,使用工厂函数返回对象很简单;但若是service方法定义服务时,AngularJS使用工厂函数返回的对象就像构造器,使用JavaScript的new关键字创建服务对象一样。

    angular.module("customServices",[])
        .service("logService",function(){
            return{
                messageCount:0,
                log:function(msg){
                    console.log(.this.messageCount++..);
                }
            }
        })

    AngularJS将暗中使用new关键字,总体效果是让service方法作为可交换的factory方法替代品。

    三、使用provider方法

    module.provider方法可以让你更好控制被创建或被配置的服务对象的方式。

    provider方法的参数是将被定义的服务的名称和工厂函数。工厂函数必须返回提供器对象,并在其中定义$get方法,它可以返回服务对象。

    需要该服务时,AngularJS将调用factory方法获得提供器对象,然后调用$get方法获得服务对象。使用provider方法的优点是你可以为provider方法添加功能,该方法可用于配置服务对象。

    AngularJS使提供器对象适用于依赖注入,使用服务的名称与Provider连接。

    angular.module("exampleApp", ["customDirectives", "customServices"])
            .config(function (logServiceProvider) { // 使用服务名+Provider
                logServiceProvider.debugEnabled(true).messageCounterEnabled(false);
            })
            .controller("defaultCtrl", function ($scope, logService) { // 使用服务名
                $scope.data = {
                    cities: ["London", "New York", "Paris"],
                    totalClicks: 0
                };
    
                $scope.$watch('data.totalClicks', function (newVal) {
                    logService.log("Total click count: " + newVal);
                });
            });
    angular.module("customServices", [])
        .provider("logService", function () {
            var counter = true;
            var debug = true;
            return {
                messageCounterEnabled: function (setting) {
                    if (angular.isDefined(setting)) {
                        counter = setting;
                        return this;
                    } else {
                        return counter;
                    }
                },
                debugEnabled: function (setting) {
                    if (angular.isDefined(setting)) {
                        debug = setting;
                        return this;
                    } else {
                        return debug;
                    }
                },
                $get: function () {
                    return {
                        messageCount: 0,
                        log: function (msg) {
                            if (debug) {
                                console.log("(LOG"
                                    + (counter ? " + " + this.messageCount++ + ") " : ") ")
                                    + msg);
                            }
                        }
                    };
                }
            }
        });

    服务对象是单例的,一旦你对已启动的应用程序作出任何改变,所有正在使用该服务的组件都将受到影响。 

  • 相关阅读:
    【http】使用浏览器Cache和http状态码304实现的客户端缓存
    delegate与模式
    用Delegate绕开频繁反射的又一个简单高效的方法
    直接调用、委托与反射调用的性能区别
    Lambda表达式的非Linq用法
    泛型+反射+特性=以静制动
    绕开频繁反射
    不要用错单例模式
    活用接口——反例:MultiKeyDictionary
    jQuery框架总体分析
  • 原文地址:https://www.cnblogs.com/YangqinCao/p/6017819.html
Copyright © 2011-2022 走看看