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

AngularJS - How to share watched objects in several controllers?

本文关键字:控制器 共享 监视 对象 AngularJS      更新时间:2023-09-26

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

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的watch在观察变量时失去了上下文,所以它不能简单地通过原型创建一个ActionStatus对象。

任何想法?

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

的例子:

// 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. 放入$rootScope
  2. 将其置于服务/工厂中,并使用消息系统($broadcast, $emit, $on)相互通信。
  3. 与第二个选项类似,只需观察objectEquality设置为true的服务,如下所示:

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