2017-01-12 21 views
4

構造AngularJS Double HTTPリクエスト、これは良い解決策ですか、何か間違っていますか?

私は2つのコントローラと1つのモデルを持っています。

  1. 注文プロセス
  2. ため
  3. ためのすべてのデータを処理するためのモデルのナビゲーションのみを処理するためのNAVコントローラの一の工程を処理するためのコントローラ。

すべての情報は、そのバンドルを構成するタブを選択したバンドルに応じて、注文オブジェクトに格納されます。

ナビゲーションの各ステップをナビゲートしている間、navコントローラは常にその作業を行い、注文コントローラは現在の特定の設定ステップに必要な異なるコントローラで変更することができます。

シナリオ

順序コントローラが初期化され、NAVコントローラが初期化された第一の状態をロードします。どちらも "OrderModel.getOrder()"メソッドを呼び出します。これはhttp呼び出しの約束です。

両方のコントローラが初期化中で、約束がまだ解決されていない場合は、apiに二重の要求が発生します。これはちょっと残念です。

ソリューション

私はユニークな新しいメソッドを追加します$ qをライブラリのラッパーを作成しました。

プロミスがまだ存在しない場合はプロミスをモデルに保存し、それ以外の場合はまだ解決されていないプロミスを返します。これにより、複数のhttp呼び出しが防止されます。

質問

このソリューションは、私が何か間違ったことをやっているように私は感じるので、簡単でわかりやすい見えますので、皆さんは、この構造/ソリューションについてどう思いますか?

例コード:

コントローラgetOrder方法:

/** 
    * @name getOrders 
    * @param force 
    * @description 
    * Get the given order 
    */ 
    function getOrder (id, force) { 
     return $q(
      function (resolve, reject) { 
       Orders.getOrder(id, force).then(
        function (order) { 
         vm.order = order; 
         resolve(order); 
        }, 
        reject 
       ); 
      } 
     ); 
    } 

モデルgetOrder方法:

function getOrder (id, force) { 
     var url = AppConfig.ApiUrl + '/order/' + id; 
     var promiseUrl = url + '-force-' + force; 

     return $qPromise.unique(promiseUrl, function (resolve, reject) { 
      if (!force && model.orders[id]) { 
       return resolve(model.orders[id]); 
      } 

      $http.get(url, { bearer: true }).then(
       function (response) { 
        model.orders[id] = response.data.data; 
        resolve(model.orders[id]); 
       }, 
       reject 
      ); 
     }); 
    } 

$ Qラッパー (関数(){

angular.module('app').factory('$qPromise', qWrapper); 

qWrapper.$inject = ['$q']; 

/** 
* @name QWrapper 
* @param $q 
* @returns {*} 
* @description 
* Wrapper arround $q to add the unique method. 
*/ 
function qWrapper($q) { 
    var model = { 
     promises: {} 
    }; 

    $q.unique = uniquePromise; 

    return $q; 

    /** 
    * @name uniquePromise 
    * @param id 
    * @param cb 
    * @description 
    * Promise wrapper for preventing multiple calls for the same data. 
    * @returns {*} 
    */ 
    function uniquePromise (id, cb) { 
     if (model.promises[id]) { 
      return model.promises[id]; 
     } 

     var promise = model.promises[id] = $q(cb); 
     promise.catch(console.warn); 

     $q.when(
      promise, 
      function() { delete model.promises[id]; }, 
      function() { delete model.promises[id]; } 
     ); 

     return promise; 
    } 
} 

})(); 
+0

この質問はお寄せいただきありがとうございます。しかし、なぜ私は両方のコントローラで 'getOrder()'メソッドを呼び出すのか疑問がありますか? –

+0

'getOrder()'のレスポンスをキャッシュして、それを呼び出すときに2回目にAPIの代わりにキャッシュにヒットするのはなぜでしょうか? – Ankh

+0

@RameshRajendranナビゲーションコントローラはナビゲーションに応じてオーダーオブジェクトを必要とするため、モデルからオーダーオブジェクトを受け取り、オーダーオブジェクトがあることを確認します。私はgetOrderとgetOrderを2回呼び出すと、すでにオブジェクトがある場合はそのオブジェクトを返すようにします。そうでなければ、http呼び出しを呼び出します。 – Sedenko

答えて

0

私はかつて、両方のhttpコールが私に特定のjsonを与えると同時に2つのhttpコールを行う必要があったシナリオに直面しました。だから私はこれをしなければならなかった、

var app=angular.module('myapp',[]); 
 

 
app.controller('contactController',function($scope,$http,$q) 
 
{ 
 
\t 
 
\t var promise1=$http.get("https://jsonplaceholder.typicode.com/posts/1"); 
 
\t var promise2=$http.get("https://jsonplaceholder.typicode.com/users/1"); 
 
$q.all([promise1, promise2]).then(function(data){ 
 
\t $scope.first=data[0]; 
 
\t $scope.second=data[1]; 
 
    console.log("------FIRST HTTP RESPONSE_____"); 
 
\t console.log(JSON.stringify($scope.first)); 
 
     console.log("------SECOND HTTP RESPONSE_____"); 
 

 
\t console.log(JSON.stringify($scope.second)); 
 
    }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script> 
 

 
<body ng-app="myapp" ng-controller="contactController"> 
 
    </body>

これは実際に動作します。 $ scope.firstは最初のhttp呼び出しの結果を返し、$ scope.secondは2回目のhttp呼び出しの結果を返します。

私はそれがあなたが必要とする目的に役立つかどうかはわかりませんが、私が知っていたことを共有しました。

+0

あなたの答えをありがとう。これはまったく異なるシナリオです。あなたは今、2つの別個の通話を話しています。どちらの通話でも、両方が解決するまで待っていますが、私の質問は異なります。 – Sedenko

関連する問題