angularjs的service


1.首先我們創建一個模塊    

var module = angular.module( "my.new.module", [] );


2.然后寫具體的service 可以看到它是一個很有趣的對象 ,以鍵值對的方式定義屬性和值, 值可能是數組,json對象數組,或者函數

appServices.service('Book',['$rootScope',function($rootScope){

    var service = {
        books: [
            {title:'bbq',anthor:'李斯'},
            {title:'barbecue',anthor:'loli'}
        ],
        addBook: function(a_book){
            service.books.push(a_book);
            $rootScope.$broadcast( 'books.update' );  
            //這里相當於定義了一個回調函數,任何調用這個圖書服務的指令,控制器,過濾器等可以選擇實現這個books.update句柄
            來進行addBook后想執行的操作,如更新$scope
        }
    }

    return service;
}]);


note:這是通常一個簡單的service的寫法
    $broadcast只能向child controller傳遞event與data
    $emit只能向parent controller傳遞event與data
    $on用於接收event與data

controller之間的層級關系 (controller可以任意嵌套):

<div class="box row" ng-controller="parentCtrl">
    <div class="col-xs-12">
        <a ng-click="clickMe()" >click me!->i belong parent controller</a>
        <div ng-controller="AChildCtrl">
            <a ng-click="clickMe()" s>click me!->i belong child&&brother controller</a>
        </div>
        <div ng-controller="BChildCtrl">
            <a ng-click="clickMe()" >click me!->i belong child&&brother controller</a>
        </div>
    </div>
</div>

 

 

$broadcast $emit $on 的應用

appCtrls.controller('parentCtrl',['$scope',function($scope){
    
     $scope.clickMe = function(){
         var book = { title:'monkey' , author:'lee' }
         $scope.$broadcast('givetochild',book);
     }    
}]);

appCtrls.controller('AChildCtrl',['$scope',function($scope){

    var book = { title:'fifty shadows' , author:'mcdownload' }
    $scope.$emit = ('givetoparent', book); //向父級傳值
}]);

appCtrls.controller('BChildCtrl',['$scope',function($scope){

    $scope.$on('givetochild',function(event,data){
        console.log(data.title + ' ' + data.author); //輸出 mokey 和 lee
        console.log(event);
    });    
}]);


比較奇怪的現象是如果

appCtrls.controller('parentCtrl',['$scope',function($scope){
    
         var book = { title:'monkey' , author:'lee' }
         $scope.$broadcast('givetochild',book);
}]);

那么總是不會觸發$on,得不到任何輸出
但是如果,總會正常得到值

appCtrls.controller('parentCtrl',['$scope','$timeout',function($scope,$timeout){
    $timeout(function(){
        var book = { title:'monkey' , author:'lee' }
        $scope.$broadcast('givetochild',book);
    },10);
}]);

 

service的使用簡單代碼實例為

template:
<div class="box row" ng-controller="books.list">
    <div class="col-xs-12">
        <p ng-repeat="book in books">{{book.title}} -- {{book.author}}</p>
        <input type="text" ng-model="book_title" placeholder="請輸入書名"><br>
        <input type="text" ng-model="book_author" placeholder="請輸入作者"><br>
        <a ng-click="addBook()">添加書籍</a>        
    </div>
</div>

controller:
var appCtrls = angular.module('appCtrls',[]);
appCtrls.controller('books.list',['$scope','Book',function($scope,Book){

    $scope.books = Book.books;  //取用圖書服務

    $scope.addBook = function(){
        var a_book = { title:$scope.book_title , author:$scope.book_author }
        Book.addBook(a_book);
    }

    $scope.$on('books.update',function(event){
        $scope.books = Book.books;
    });

}]);

service:
var appServices = angular.module('appCtrls');
appServices.service('Book',['$rootScope',function($rootScope){

    var service = {
        books: [
            {title:'bbq',author:'李斯'},
            {title:'barbecue',author:'loli'}
        ],
        addBook: function(a_book){
            service.books.push(a_book);
            $rootScope.$broadcast( 'books.update' );
        }
    }

    return service;
}]);

此外,$on還暴露了更多我們可以用到的東西,如果你需要的話
在$on的方法中的event事件參數,其對象的屬性和方法如下

事件屬性                                 目的
event.targetScope                  發出或者傳播原始事件的作用域
event.currentScope                 目前正在處理的事件的作用域
event.name                         事件名稱
event.stopPropagation()            一個防止事件進一步傳播(冒泡/捕獲)的函數(這只適用使用`$emit`發出的事件)
event.preventDefault() 這個方法實際上不會做什么事,但是會設置`defaultPrevented`為true。
直到事件監聽器的實現者采取行動之前它才會檢查`defaultPrevented`的值。
event.defaultPrevented 如果調用了`preventDefault`則為true

 

angular 十分推崇以模塊化的方式組織代碼,從而管理數據,處理頁面交互等

你可以看到我們總是先 var xxx= angular.module('xxx',[]) (先創建模塊),然后你可以試試console.log(xxx);

你可以看到模塊下的屬性, constant是module的,service是module的,controller是module,filter是module的,animation是module的

它們的值都是一個function,在module啟動后,由angularjs框架封裝好的getter setter去invoke我們定義的對應的service,controller....

所以使用service來管理數據比控制器注入的scope要好的多,當你要在多個控制器間分享數據時,當任何時候控制器需要某些數據時,你可以使用注入service的方式,得到數據,

更好的是當你要跨域名分享數據時,你顯然只需要在根module,或者什么地方的模塊定義了service,然后引入這個第三方module的js文件就可以了,

你可能會擔心不夠clean,但是這完全不是問題,因為還記得angular的依賴注入系統麻,在你的app啟動的module定義時加入注入這個module即可,這樣這個module可以做得十分clean.

更有意思的一件事情是 service數據來源的方式不是constant或者Value, 通過service你完全使用異步$http之類的來得到數據

所以代碼可以這樣組織

var appServices = angular.module('appServices',[]);  //這時我們給數據服務單獨了一個模塊

//然后我們讓service 使用$http的方式,而不是直接定義數據
appServices.service('Book',['$rootScope', '$http',function($rootScope,$http){

    var service = {
        books: [
            {title:'bbq',author:'李斯'},{},{},...
        ],
        addBook: function(a_book){  ....        },
        booksNext: function(){
            var req = {
                url: 'http://www.baidu.com',
                params: {
                    name: 'lee',
                    phone: 13243244176
                }
            }
            $http(req)
                .success(function(data,status){
                    console.log(data);console.log('is success');
                })
                .error(function(data,status){
                    console.log(data);console.log('is error');
                });
        }
    }

    return service;
}]);

然后我們的應用程序啟動時這樣的結構

//在根module這樣
var app = angular.module('app', [
    'appCtrls',
    'appFilters',
    'appDirectives',
    'appServices', //這里注入
    'infinite-scroll',
    'ngRoute',
    'ngSanitize',
    'ngStorage'
]);

//或者在這里注入 
var appCtrls = angular.module('appCtrls',['appServices']);

然后在控制器里具體使用(十分簡單)

appCtrls.controller('books.list',['$scope','Book',function($scope,Book){

    $scope.books = Book.books;  //取用圖書服務
    Book.booksNext(); //取用圖書列表的下一頁
}]);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM