AngularJS - 如何在多个控制器中共享监视对象?

时间:2014-03-12 10:40:45

标签: javascript angularjs

我当前的控制器充满了隐藏提交按钮的逻辑,并在后端提取数据后显示成功消息:

angular.module('testApp').controller('TestCtrl', ['$scope', 'testService',
    function ($scope, testService) {

    $scope.loading = false;
    $scope.updated = false;
    $scope.error = false;

    $scope.submit = function() {
      if(!$scope.form.$valid) {
        return;
      }

      $scope.loading = true;
      testService.doBackendUpdate({some:'data'})
        .success(function() {
          $scope.error = $scope.loading = false;
          $scope.updated = true;
        })
        .error(function(error) {
          $scope.updated = $scope.loading = false;
          $scope.error = true;
        });
    };
  }]);

和html:

 <alert type="'success'" close="updated = false" ng-show="updated">Data Updated!</alert>

 <button ng-hide="loading">update</button>

我希望拥有的代替那些变量是某种对象,并重用它 在其他控制器上:

angular.module('testApp').controller('TestCtrl', ['$scope', 'testService',
    function ($scope, testService) {

    $scope.status = new ActionStatus();

    $scope.submit = function() {
      if(!$scope.form.$valid) {
        return;
      }

      $scope.status.loading();
      testService.doBackendUpdate({some:'data'})
        .success(function() {
          $scope.status.succes();
        })
        .error(function(error) {
          $scope.status.error();
        });
    };
  }]);

和html:

 <alert type="'success'" close="updated = false" ng-show="status.isUpdated">Data Updated!</alert>

 <button ng-hide="statuss.isLoading">update</button>

但我怎么能做到这一点? AngularJS手表在观察变量时会丢失上下文,所以我不能简单地通过原型设计创建一个ActionStatus对象。

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

要在多个控制器之间共享对象,您应该创建一个服务。

示例:

// Custom object
function ActionStatus() {
  this.isLoading = false;
  this.updated = false;
  this.error = false;
  this.loading = function() {};

}

angular.module('testApp').service('actionStatus', [ActionStatus]);

// Inject object factory dependency to your controller.
angular.module('testApp').controller('TestCtrl', ['$scope', 'testService', 'actionStatus',
function ($scope, testService, actionStatus ) {

 $scope.status = actionStatus;

 }]);

这里的问题是服务是单例,并使用new关键字进行实例化。

要共享对象原型并自行处理实例化,可以使用工厂方法。工厂应该像这样返回原型的构造函数:

app.factory('actionStatus', [function() {

 // Define constructor
 function ActionStatus() {
   this.isLoading = false;
   this.updated = false;
   this.error = false;
   this.loading = function() {};
   this.stopLoading = function() {
    this.isLoading = false;
   };
 }

 // Return constructor to handle the instantiation yourself.
 return ActionStatus; 
}]);

我为你创建了一个关于plnkr的工作示例:http://plnkr.co/edit/Wd4kmg?p=preview

更多信息:

http://code.angularjs.org/1.2.14/docs/guide/providers

答案 1 :(得分:0)

我可以考虑三种方式:

  1. 将其放入$rootScope
  2. 将其放入服务/工厂,并使用消息传递系统($broadcast$emit$on)进行相互通信。
  3. 与第二个选项类似,只需按objectEquality设置为true即可观看服务,如下所示:

    $watch(WhateverService.get(), functiondoTheJob(){...}, true)