在AngularJS中共享控制器之间的可观察数组引用

时间:2013-01-15 15:45:54

标签: angularjs

我正在编写一个AngularJS应用程序,其中一个数组(活动工单的列表)在许多不同的控制器中使用。使用$http调用服务器定期刷新此数组。为了分享这些信息,我已将数组放入服务中。

服务中的数组开始为空(或者,出于调试目的,使用虚拟值["A", "B", "C"]),然后查询服务器以初始化列表。不幸的是,我的所有控制器似乎都被绑定到数组的预先查询版本 - 在我的应用程序中,我看到的是我用数组初始化数组的虚拟值。

我的目标是将数组绑定到我的控制器中,以便Angular能够意识到数组已经更新并导致我的视​​图在数组更改时重新呈现,而不必引入$watch或强制我的$http来电等待结果。

问题:如何将wo_list数组从我的服务绑定到我的控制器,以便Angular将其视为模型的常规可观察部分?

我有:

  1. 包含数组和刷新函数的服务,用于从服务器初始化和定期更新数组(我知道这是通过console.log()消息工作)。出于调试目的,我使用占位符“A”,“B”和“C”初始化数组 - 实际工作订单是五位数字符串。

    angular.module('activeplant', []).
       service('workOrderService', function($http) {
    
       wo_list = ["A", "B", "C"]; //Dummy data, but this is what's bound in the controllers.
    
       refreshList = function() {
             $http.get('work_orders').success(function(data) {
                 wo_list = data;
                 console.log(wo_list) // shows wo_list correctly populated.
             })
       }
    
       refreshList();
    
       return {
    
           wonums: wo_list,  // I want to return an observable array here.
    
           refresh:  function() {
             refreshList();
           }
    
       }
     })
    
  2. 应该绑定到workOrderService中的数组的控制器,以便显示工作单列表。我将服务和服务返回的数组绑定在两个不同的尝试中,以使其工作。

    function PlantCtrl($scope, $http, workOrderService) {
      $scope.depts      = []
      $scope.lastUpdate = null
      $scope.workorders = workOrderService
      $scope.wonums     = workOrderService.wonums  // I want this to be observable
    
      $scope.refresh = function() {
          $scope.workorders.refresh()
          $http.get('plant_status').success(function(data) {
              $scope.depts = data;
              $scope.lastUpdate = new Date()
          }); 
      }
    
      $scope.refresh()
    
    }
    
  3. 一个视图模板,它迭代工厂控制器中的绑定数组以打印工作单列表。我正在尝试两次尝试使用它,最终版本只有一次ul元素。

    <div ng-controller="PlantCtrl">
      <div style='float:left;background-color:red' width="20%">
          <h2>Work Orders</h2>
          <ul>
             <li ng-repeat="wonum in workorders.wonums"><a href=""> {{wonum}} </a></li>
          </ul>
          <ul>
              <li ng-repeat="wonum in wonums"><a href=""> {{wonum}} </a></li>
          </ul>
      </div>
    </div>
    
  4. 此处未显示的其他几个视图/控制器对也绑定并迭代工作单数组。

2 个答案:

答案 0 :(得分:16)

看看这是否解决了您的问题:

而不是wo_list = data,填充相同的数组。当您将新的data数组分配给wo_list时,会丢失与旧数组的绑定 - 即,您的控制器可能仍然绑定到先前的data数组。

wo_list.length = 0
for(var i = 0; i < data.length; i++){
    wo_list.push(data[i]);
}

有关详细信息,请参阅https://stackoverflow.com/a/12287364/215945

可以/应该使用

更新: angular.copy()

angular.copy(data, wo_list);

当向copy()方法提供目标时,它将首先删除目标的元素,然后从源中复制新的元素。

答案 1 :(得分:2)

您可以将所有控制器使用的阵列放在父控制器中。由于范围继承自更高的范围,这意味着所有控制器都具有相同的数组副本。由于数组是较高范围的模型,因此更改视图时,无论何时使用它都会更新视图。

示例:

<div ng-controller="MainControllerWithYourArray">
    <div ng-controller="PlantCtrl">
         Wonums length: {{wonums.length}}
    </div>
    <div ng-controller="SecondCtrl">
         Wonums length in other controller: {{wonums.length}}
    </div>
</div>

您只需要在MainController中定义wonums数组:

function MainControllerWithYourArray($scope, workOrderService){
    $scope.wonums = workOrderService.wonums;
}

希望这适合你!