Angular 控制器之間的數據共享與通訊

撰寫於 2016年7月28日 修改於 2016年7月28日 分類編程雜記 標籤AngularJS /JavaScript /前端前端

AngularJS 自己已經提供了像指令 Directive 和 服務 Service 一類的方式,來實現數據和代碼的共享和複用,但在實際的項目開發中,或許是處於懶惰,亦或是爲了便利,總會想在兩個控制器之間,直接進行數據的共享編程

通訊,或者是函數與方法的調用,這裏咱們就看看有哪些方法能夠知足這個要求。app

單例服務

單例服務是 AngularJS 自己支持的數據和代碼共享方式,由於是單例的,全部的控制器訪問的即是同一份數據。好比,下面的 Service 即可以實現:函數

angular
  .module('app')
  .service('ObjectService', [ObjectService]);
function ObjectService() {
  var list = {};
  return {
    get: function(id){
      return list[id];
    },
    set: function(id, v){
      list[id] = v;
    }
  };
}

在一個控制器中,調用 ObjectService.set('i', 1) 設置的數據,在其它控制器中,即可以經過 ObjectService.get('i') 來獲取。spa

廣播與事件

AngularJS 中在觸發事件和發送廣播時,均可以傳遞參數,能夠經過這一特性,來實現數據的共享。與事件和廣播相關的,共有三個方法,分別是:code

  • $emit() :觸發事件,它能夠向上傳遞數據,好比,子控制器向父控制器,還有控制器向 $rootScope
  • $broadcast() :發送廣播,它能夠向下傳遞數據,好比,父控制器向子控制器傳遞數據,或者 $rootScope 向任意控制器傳遞數據
  • $on() :監聽事件與廣播,能夠捕獲 $emit 和 $broadcast

能夠將控制器之間的通訊,分爲三種情形:事件

  • 無直接關聯的控制器:使用 $rootScope.$emit() 、 $rootScope.$boardcast() 或 $scope.$emit 來發出數據,經過 $rootScope.$on() 來獲取數據
  • 父控制器到子控制器:父控制器使用 $scope.$boradcast() 來發送數據,子控制器經過 $scope.$on() 來獲取數據
  • 子控制器至父控制器:子控制器使用 $scope.$emit() 來發送數據,父控制器經過 $scope.$on() 來獲取數據

下面是簡單的用法:ip

// one controller
angular
  .module('app')
  .controller('OneController', ['$scope', OneController]);
function OneController($scope){
  var data = {value: 'test'};
  $rootScope.$broadcast('open.notice.editor', data);
}

// other controller
angular
  .module('app')
  .controller('AnotherController', ['$scope', AnotherController]);
function AnotherController($scope){
  $scope.$on('open.notice.editor', function(event, data){
    $scope.open(data);
    $scope.$emit('notice.editor.opened');
  });
}

父控制器

若是兩個控制器共同擁有同一個父控制器,則能夠經過父控制器來進行數據共享和通訊。好比:element

<div ng-controller="ParentController">
  <div ng-controller="ChildOneController"></div>
  <div ng-controller="ChildTwoController"></div>
</div>
// 父控制器
angular
  .module('app')
  .controller('ParentController', ['$scope', ParentController]);
function ParentController($scope){
  // 用於傳遞數據的變量
  $scope.data = null;
}

// 子控制器
angular
  .module('app')
  .controller('ChildOneController', ['$scope', ChildOneController]);
function ChildOneController($scope){
  // 數據設置
  $scope.$parent.data = 1;
}

// 子控制器
angular
  .module('app')
  .controller('ChildTwoController', ['$scope', '$timeout', ChildTwoController]);
function ChildTwoController($scope, $timeout){
  $timeout(function(){
    // 數據讀取
    console.log($scope.$parent.data);
  }, 1000);
}

全局或共用的變量

AngularJS 提供了對 window 和 localStorage 兩個變量的封裝, $window 和$localStorage ,經過修改和監聽這兩個值,能夠達到在控制器之間數據共享和通訊的目的。方法以下:開發

// one controller
angular
  .module('app')
  .controller('OneController', ['$scope', '$window', OneController]);
function OneController($scope, $window){
  // 數據設置
  $window.data = 1;
}

// other controller
angular
  .module('app')
  .controller('AnotherController', ['$scope', AnotherController]);
function AnotherController($scope){
  // 監聽修改
  $scope.$watch(function(){
    return $window.data;
  }, function(n){
    $scope.windowData = n;
  });
}

其實,這種監聽修改的方式,也能夠用在其它通訊方式中。

元素綁定

AngularJS 中,能夠經過一個元素,來獲取其上的控制器實例。經過這種方式即可以快速的獲取

修改某個控制器中的數據,或者調用這個控制器中的方法。好比:

<div ng-controller="AppController">
  <div id="div-a"></div>
</div>

能夠經過如下的方法,來獲取控制器實例:

var instance = angular.element(document.getElementById('div-a')).scope();

接着,即可以經過這個 instance 來調用控制器的方法,獲取和修改值了。沒法是元素自己綁定有控制器,仍是元素的父級元素綁定有控制器,均可以成功的獲取。

茴字有不少寫法,具體寫的時候用哪一種,徹底看狀況和心情。

相關文章
相關標籤/搜索