2

$resource リクエストを単純なラッパーでラップする作業を行っています。主なアイデアは、リクエストが行われる前にいくつかのロジックを追加できるようにすることです。Nilsが書いた素敵な記事をフォローしました。

ここでは、REST API モジュールにアクセスするためのサービス定義を確認できます。

resources.factory('Device', ['RequestWrapper', '$resource', 'lelylan.config', function(RequestWrapper, $http, config) {
  var resource = $resource(config.endpoint + '/devices/:id', { id: '@id' });
  return RequestWrapper.wrap(resource, ['get', 'query', 'save', 'delete']);
}]);

ここでは、リクエスト ラッパーの定義を確認できます。

resources.factory('RequestWrapper', ['AccessToken', function(AccessToken) {
  var requestWrapper = {};
  var token;

  requestWrapper.wrap = function(resource, actions) {
    token = AccessToken.initialize();

    var wrappedResource = resource;
    for (var i=0; i < actions.length; i++) { request(wrappedResource, actions[i]); };
    return wrappedResource;
  };

  var request = function(resource, action) {
    resource['_' + action]  = resource[action];

    resource[action] = function(param, data, success, error) {
      (AccessToken.get().access_token) ? setAuthorizationHeader() : deleteAuthorizationHeader()
      return resource['_' + action](param, data, success, error);
    };
  };

  var setAuthorizationHeader = function() {
    $http.defaults.headers.common['Authorization'] = 'Bearer ' + token.access_token;
  };

  var deleteAuthorizationHeader = function() {
    delete $http.defaults.headers.common['Authorization']
  };

  return requestWrapper;
}]);

GET および DELETE メソッド (本体を返さないメソッドのようです) ではすべてが正常に機能しますが、$save が機能しません。何が起こるかというと、作成されたリソースの JSON が返されたときに追加されません。作成段階で設定したデータしかありません。例を挙げましょう。

この場合、ラップされたリソースを使用します。#updated_at 属性を取得しようとすると、表示されません。Chrome インスペクターで、リソースが正常に作成されたことを確認できます。

$scope.device = new Device({ name: 'Angular light', type: 'http://localhost:9000/types/50bf5af4d033a95486000002' });
$scope.device.$save(function(){ console.log('Device Wrapped', $scope.device.created_at) });
# => undefined

$resource を使用すると、すべて正常に動作します。

// Suppose authorization is already set
var Resource = $resource('http://localhost\\:9000/devices/:id');
$scope.resource = new Resource({ name: 'Angular light', type: 'http://localhost:9000/types/50bf5af4d033a95486000002' });
$scope.resource.$save(function(){ console.log('Device Base', $scope.resource.created_at); });
# => 2013-02-09T12:26:01Z

angular-resource.js コードのチェックを開始しましたが、数時間後、実際には理解できませんでした。本文が返される理由はわかりませんが、ラッパー リソースではアクセスできません。

どんなアイデアや助けもいただければ幸いです。ありがとう。

4

1 に答える 1

2

While diving into AngularJS source code I've found the solution.

The problem was that the wrapper was returning a function instead of an object and this was giving some problems. The solution is to change the following row in the Wrapper:

return resource['_' + action](param, data, success, error);

with this one:

return resource['_' + action].call(this, params, data, success, error);

Why? The fast answer is because in the source code of angular-resource they use it. Actually #call run the function sending this to the calling object. It is often used to initialize an object. Learn more here.

于 2013-02-09T15:50:13.017 に答える