2013-07-16 20 views
41

単純な$ http要求をサーバーに使用したり、サービスでその要求をラップしたり、ngResourceオブジェクトを使用するよりも長所と短所を理解したいと思います。 RESTfulなリソース)。

$ httpリクエストは低レベルですが、非常に柔軟で設定可能ですが、RESTful APIを扱う場合、ngResourceオブジェクトは通信を非常に簡単にします。

サーバからのデータ取得(オブジェクトの配列のGETリクエスト)という単純なシナリオが非常に単純なシナリオで与えられていると思いますが、どちらかのラッピングではなく$ httpリクエストを使用する方が効率的ですそれはサービスで(これは常にそうであるべきですか?)またはngResourceオブジェクトを使用していますか?

ここでのご意見をお待ちしております。たとえば、$ http応答をキャッシュすることはできますか?ngResourceは可能ですか?ありがとう。

を$ httpまたは$結果がまだキャッシュできるリソースを使用して、あなたにその理由を指摘した:私たちは、あなたが知りたいと思ったものを基本的に働いたコメントで以来、私は答えにこれを定式化するだろうことを決めた

+3

両方をキャッシュすることができます。あなたは、あなたの質問にもう一方を使用する理由を指摘しました。 RESTfulなインターフェースをお持ちの場合は、RESTfulなインターフェースを使用していない場合は、$ httpがより理にかなっていれば、RESTfulインターフェースに共通のボイラー・プレート・コードを書き留めてしまうので、$ resourceを使用する方が良いです。データをいずれかの方法でキャッシュすることができますhttp://pseudobry.com/power-up-%24http.htmlこれがあなたの質問に答えるなら私に教えてください。私はそれを回答として投稿し、コメントを削除します。 – shaunhusain

+1

返答ありがとうございます、私は思っていますが、$ HTTPとngResourceの利点/利点が、おそらくRESTful APIからオブジェクトを返すが、 GET以外のインタラクションはありません。たぶん私はそれに多くを読んでいる、ちょうど議論されたユースケースを見つけることができなかった、実装のみ。 $ http要求がサービスにラップされるべきだが、ベストプラクティスが見つからないとの議論もある。 – adamK

+3

$ httpリクエストをサービスに入れるのは、複数の場所からのデータへのアクセスを必要とし、サービスがシングルトンとして機能するので、一般的にうまく機能すると思います。基本的には、すべて自分のデータを更新するための適切なサービスを見るだけです。私は、コントローラの$ watchのコンビネーションが、サービスに関するデータと私のサービスのメソッドからの約束を返すことで、コントローラの中のものを更新する方法に最も柔軟になることがわかりました。 – shaunhusain

答えて

42

本当にあなたの質問でもう一方を使ってください。 RESTfulなインターフェースをお持ちの場合は、RESTfulなインターフェースを使用していない場合は、$ httpがより理にかなっていれば、RESTfulインターフェースに共通のボイラー・プレート・コードを書き留めてしまうので、$ resourceを使用する方が良いです。あなたはデータをいずれかの方法でキャッシュすることができますhttp://www.pseudobry.com/power-up-http-with-caching/

サービスに$ httpまたは$リソースリクエストを入れることは、複数の場所からのデータへのアクセスを必要とし、サービスがシングルトンとして機能するため、一般的には効果的です。したがって、基本的には、そこでやりたいあらゆる種類のキャッシュを扱うことができ、コントローラーはすべて自分のデータを更新するための適切なサービスを見ることができます。私は、コントローラの$ watchのコンビネーションが、サービスに関するデータと私のサービスのメソッドからの約束を返すことで、コントローラの中のものを更新する方法に最も柔軟になることがわかりました。

コントローラの定義の先頭にexampleServiceが挿入されているように、このようなものを私のコントローラに配置します。

angular.module("exampleApp", []).service('exampleService', ["$http", "$q" ,function ($http, $q) { 
    var service = { 
     returnedData: [], 
     dataLoaded:{}, 
     getData = function(forceRefresh) 
     { 
      var deferred = $q.defer(); 

      if(!service.dataLoaded.genericData || forceRefresh) 
      { 
       $http.get("php/getSomeData.php").success(function(data){ 
        //service.returnedData = data; 
        //As Mark mentions in the comments below the line above could be replaced by 
        angular.copy(data, service.returnedData); 
        //if the intention of the watch is just to update the data 
        //in which case the watch is unnecessary and data can 
        //be passed directly from the service to the controller 
        service.dataLoaded.genericData = true; 
        deferred.resolve(service.returnedData); 
       }); 
      } 
      else 
      { 
       deferred.resolve(service.returnedData); 
      } 

      return deferred.promise; 
     }, 
     addSomeData:function(someDataToAdd) 
     { 
      $http.post("php/addSomeData.php", someDataToAdd).success(function(data){ 
       service.getData(true); 
      }); 
     } 
    }; 
    service.getData(); 
    return service; 
}]).controller("ExampleCtrl", ["$scope", "exampleService", function($scope, exampleService){ 
    //$scope.$watch(function() {return exampleService.returnedData}, function(returnedData){ 
    // $scope.myModel.someData = returnedData; 
    //}); 
    //if not using angular.copy() in service just use watch above 
    $scope.myModel.someData = exampleService.returnedData; 
}]); 

はまた、ここで私はまだ再見て、ゆっくりと時間をかけて吸収してるのベストプラクティスの角度チームからの素敵なビデオです。

サービス対コントローラ上の具体的

http://www.youtube.com/watch?v=ZhfUv0spHCY

http://www.youtube.com/watch?v=ZhfUv0spHCY&t=26m41s

+13

+1。あなたのサービスで 'angular.copy(data、service.returnedData)'を使うと、コントローラの '$ watch 'を取り除くことができます。この方法では、新しい配列を割り当てるのではなく、同じ配列を更新します。作業中のプランナーについては、http://stackoverflow.com/questions/17416599/should-services-expose-their-asynchronicity –

+1

リンクをここに移動してください:http://www.pseudobry.com/power-up-http-with -caching/ – Casey

5

彼らはキャッシュされてできるかどうかよりも1つのはるかに有意義な違いがあります。

リソースを使用すると、サービスまたは返されたデータに$ watchesを設定する必要がなくなります。あなたは、どちらも約束事をする必要はありません。本質的には、シャンフーサインが彼の例で何をしているのかを行う必要はありません。

リソースメソッドを呼び出すと、そのリソースに関連付けられている構造体の空のインスタンスが返されます。これを直接バインドすることも、バインドすることもできます。この同じインスタンスは、後でデータでいっぱいになります。インスタンスにバインドしているので、入力が完了すると、ディスプレイは自動的に更新されます。

リソースは、提供するサービスの要求と応答を変換し、リソースのクライアントにすべて見えないようにカプセル化された手段を提供することもできます。

リソースはステロイドのサービスに似ています。

+0

ちょうどこの答えに気づいた。私はこれについて多くの意見に同意しない。 $ watchesは、オブジェクト自体ではなくオブジェクトの内容を置き換えるためにangular.copyを使用するだけで、どちらの場合でも問題になります。サービスは、シングルトンである注射可能なオブジェクトを定義することを可能にします。私はそれを多かれ少なかれ実際には見ません。 A $リソースは、$ httpを繰り返し使用してRESTfulなものを処理するための、$ httpの上にある抽象概念です。約束は、リクエストの非同期性を公開し、リソース上で$ promiseで取得することもできます(良いことです)。 – shaunhusain

+0

私は、フォームフィールドや一般的なビジネスエラーに関連するサーバー入力エラーやビジネス検証エラーからさまざまな種類のエラーを受け取るか、「このレコードは他のユーザーによって編集されました。再読み込みしてください」、またはユーザーセッション非アクティブまたは予期しないサーバーエラーのために失効します。これらのエラーの一部は、エラーの種類に応じてHTTP 500または422または401、または「error [key]」として返されます。 Central $ httpラッパーを使用すると、これらのエラーをすべて1か所で簡単に処理できます。 $ resourceを使用している場合、これらのエラーをどのように処理するのかは分かりません。 – JustAMartin

+0

@JustAMartin $ resourceを使用しても、内部的には$ httpで動作するので、すべてのサーバー要求と応答をグローバルに代行受信でき、エラーをグローバルに処理できます。 – Mukun