2013-04-05 8 views
9

Mam $resource którego API zawsze zwróci niektóre dane, które należy oczyścić przed wejściem do warstwy prezentacji. W szczególności jest to .NET zwracające obiekty Date w uroczym formacie '/Date(...)/'.

Nie chcę pisać oddzwonienia za każdym razem, gdy dzwonię pod numer .query() lub .get(). Czy istnieje sposób na rozszerzenie zasobu o wywołanie zwrotne, które jest wywoływane w przypadku metod REST, które aktualizują właściwości instancji, lub poprzez dodanie pewnego rodzaju obiektu $watch, który zostanie zwolniony po zmianie właściwości daty? Zasadniczo coś, co stanie się dla każdego wystąpienia tego $resource.

angular.module('myAppServices', ['ngResource']) 
    .factory('Participant', ['$resource', function ($resource) { 
     var res = $resource('api/url/participants/:id', { id: '@id' }); 

     // This obviously doesn't work, but something kinda like this? 
     res.prototype.$watch(this.FieldName, function(newVal, oldVal) { 
      if (needsCleaning(newVal.fieldName) { 
       this.FieldName = cleanupField(newVal); 
      } 
     }; 
    }); 
+0

możesz spróbować. 'var uczestnik = $ zasób ('api/url/participants /: id', {id: '@id'}}); var commonCallback = function() { \t // wewnątrz tego wywołania zwrotnego uczestnik jest zapełnionym modelem, \t // możesz użyć obiektu uczestnika do wykonania logiki formatowania. \t // Następnie, jeśli chcesz zapisać obiekt uczestnika, wykonaj \t //participant.$save(); Nie używaj nazw metod z przedrostkiem $, które będą dostępne dla instancji zasobów. } res.query (commonCallback) lub res.get ({..}, commonCallback) ' – rajkamal

Odpowiedz

12

Ah-ha, znalazłem sposób obejścia tego i zostawię to tutaj. W wersji 1.1.2 dodano obsługę przekazywania wszystkich opcji $http.config do $resource. Oczywiście, CDN, którego używam, nie ma najnowszej wersji angular-resource.js, ale zmiana CDNs rozwiązała to.

Właśnie użyłem opcji transformResponse, aby zmodyfikować dane po ich powrocie.

angular.module('myAppServices', ['ngResource']) 
    .factory('Participant', ['$resource', '$http', function ($resource, $http) { 
     var res = $resource('api/url/participants/:id', { id: '@id' }, { 
     save: { 
      method: 'POST', 
      transformResponse: $http.defaults.transformResponse.concat([ 
       function (data, headersGetter) { 
        data.FieldName = yourDateParsingFunction(data.FieldName); 

        return data; 
       } 
      ]) 
     } 
    }); 

jestem po prostu dodanie mój transformator na $httpProvider „s transformResponse, który zrobi wszystko deserializacji itp

+1

Dzięki , Podoba mi się część '$ http.defaults.transformResponse.concat'. – jvannistelrooy

+0

Uwaga: nie można używać żądania AJAX w 'transformResponse' do modyfikowania pól obiektu' data' – MyTitle

+0

Musiałem dodać instrukcję return na końcu funkcji fabryki, aby działało. – rodowi

8

Łatwym sposobem, aby to zrobić, to zastąpić istniejące $resource metod chcesz robić po zakończeniu przetwarzania na własne. Zobacz poniższy kod i komentarze na przykład.

angular.module('myAppServices', ['ngResource']) 
    .factory('Participant', ['$resource', function ($resource) { 
     var res = $resource('api/url/participants/:id', { id: '@id' }, { 
      // create aliases for query and get to be used later 
      _query: { method: 'GET', isArray: true }, 
      _get: { method: 'GET' } 
     }); 

     // redefine the query method 
     res.query = function() { 
      // call the original query method via the _query alias, chaining $then to facilitate 
      // processing the data 
      res._query.apply(null, arguments).$then(function(res) { 
       var data = res.data; 
       // do any processing you need to do with data here 
       return data; 
      }); 
     }; 

     // redefine the method 
     res.get = function() { 
      // call the original get method via the _get alias, chaining $then to facilitate 
      // processing the data 
      res._get.apply(null, arguments).$then(function(res) { 
       var data = res.data; 
       // do any processing you need to do with data here 
       return data; 
      }); 
     }; 

     return res; 
    }); 

Można by go używać w taki sam sposób aktualnie używanego Participant w kodzie, poprzez Participant.query() lub Participant.get(). Dane, które zwrócisz w łańcuchu $, a następnie moduł obsługi, zostaną użyte do rozstrzygnięcia obietnicy zwróconej przez $resource.

+0

Dzięki za odpowiedź. Nie jestem w 100% pewny, ale myślę, że "transformResponse" może być łatwiejszy do wykonania. – c0bra

+1

@ c0bra, sposób Intelekshual jest przydatny, gdy potrzebujesz dostępu do zmiennych, które nie są dostępne w 'transformResponse' – jvannistelrooy

+0

Kolejną zaletą tego rozwiązania jest to, że możemy ponownie użyć domyślnych metod z $ zasobów, aby stworzyć nasze niestandardowe metody, a następnie łatwo przekształcać odpowiedzi. –

0

The Way I tak było przez dodanie usługi dla modułu:

angular.module('keeniolab', ['ngResource']). 
factory('KeenIO',function ($resource) { 
    // factory implementation 
}).service('KeenModel', function (KeenIO) { 
    var KeenSession = function() { 
     this.data = {}; 
    }; 

    KeenSession.prototype.fetch = function (query) { 
     var self = this; 

     KeenIO.get(query, function (result) { 
      self.data = result; 
     }); 
    }; 

    return new KeenSession(); 
}); 

teraz możesz po prostu monitorować kolekcji:

$scope.$watchCollection(function() { 
    return KeenModel.data; 
}, 
function (value) { 
    // code here 
}); 

Keen.IO Resource Factory with Service Model

Powiązane problemy