11

1 つの配列 (アクティブな作業指示書のリスト) が多くの異なるコントローラーで使用される AngularJS アプリケーションを作成しています。この配列は$http、サーバーへの呼び出しを使用して定期的に更新されます。この情報を共有するために、アレイをサービスに配置しました。

サービス内の配列は空 (または、デバッグ目的でダミー値["A", "B", "C"]) で開始し、サーバーにクエリを実行してリストを初期化します。残念ながら、私のコントローラーはすべて、配列の事前にクエリされたバージョンにバインドされているようです。私のアプリケーションでは、配列を初期化したダミーの値しか表示されません。

$watch私の目標は、 Angularが配列が更新されたことを認識し、配列が変更されたときにビューを再レンダリングするように、配列をコントローラーにバインドすることです$http。 .

質問: wo_list 配列をサービスからコントローラーにバインドして、Angular がそれをモデルの通常の監視可能な部分のように扱うにはどうすればよいですか?

私は持っている:

  1. サーバーから配列を初期化し、定期的に更新するために使用される配列と更新機能を含むサービス (これはメッセージによって機能していることがわかりconsole.log()ます)。デバッグの目的で、プレースホルダー "A"、"B"、および "C" を使用して配列を初期化しています。実際の作業指示は 5 桁の文字列です。

    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 の配列にバインドするコントローラー。これを機能させるために、サービスとサービスによって返される配列の両方を 2 つの異なる試みでバインドしています。

    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. プラント コントローラーでバインドされた配列を反復処理して、作業指示書のリストを出力するビュー テンプレート。これを機能させるために 2 回試みていますが、最終バージョンには ul 要素が 1 回しかありません。

    <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. ここには示されていませんが、作業指示書の配列をバインドして反復する他のいくつかのビュー/コントローラーのペアもあります。

4

2 に答える 2

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() メソッドに提供されると、まず宛先の要素が削除され、次にソースから新しい要素がコピーされます。

于 2013-01-15T16:53:48.717 に答える
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;
}

これがうまくいくことを願っています!

于 2013-01-15T16:43:17.147 に答える