2012-10-04 13 views
9

Używam usługi Angular $resource dla usługi REST. Ze względu na dziwne zachowanie, nie mogę użyć usługi $ resource dla aplikacji CRUD.

Tworzenie nowej pracy obiektu (powiedzmy na karcie), smilar do:

var newCard = new CreditCard(); 
newCard.name = "Mike Smith"; 
newCard.$save(); 

Get działa również:

var card = CreditCard().get({_id:1) 

Ale odpowiedź GET nie jest przedmiotem Card sama, ale inna wiadomość z nim (obiekt opakowujący)

, więc gdy zapiszę instancję wyszukiwania poprzez zasoby, wysyła obiekt opakowania (ze zmodyfikowanym obiektem Card w polu odpowiedzi). To prawdopodobnie poprawne, ale mój serwer oczekuje, że obiekt karty nie będzie opakowaniem. Czy istnieje sposób dostosowania zasobu $ tak, aby wysyłał żądany obiekt. Z dokumentu wygląda na to, że tylko parametry adresu URL można zmienić.

$resource(url[, paramDefaults][, actions]); 
+0

Czy możesz zamieścić pełny przykład na jsfiddle lub podobnym? Z mojego doświadczenia wynika, że ​​w przypadku (zwykłego) CRUD nie jest konieczne tworzenie nowego obiektu w ten sposób. Co, jeśli po prostu uzyskasz dostęp do zasobu, np. $ Scope.card = Card.get ({_ id: 1), gdzie Card jest twoją usługą zasobów? Jeśli powiesz formularzowi, jaki jest twój model, instancja zostanie automatycznie wypełniona. – Narretz

+0

Nie sądzę, że twoje problemy są w Angular. Brzmi prawie tak, jak twoja implementacja REST na serwerze ma pewne problemy. Nie powinien być dołączony do niej komunikat. Możesz to najpierw sprawdzić, aby upewnić się, że treść odpowiedzi jest tylko oczekiwanym obiektem. –

+0

Serwer rzeczywiście wysyła opakowanie wokół rzeczywistego obiektu. Nadal istnieje sposób, aby wysłać tylko obiekt, gdy wysłać z powrotem na serwer (POST) – bsr

Odpowiedz

17

Mam również problemy ze standardową implementacją w module $ resource. Przez pewien czas właśnie wprowadzałem zmiany w mojej lokalnej kopii pliku zasobów $, ale odkryłem, że nadal nie jestem zadowolony ze sposobu wdrożenia zasobów REST. Potrzebowałem większej elastyczności niż oferowano.

Standardowy moduł $resource to tylko opakowanie fabryczne o wartości $ http. Jeśli sprowadzisz kod w module $ resource, możesz dość łatwo stworzyć własną implementację.

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

app.factory('CreditCard', ['$http', function($http) { 

    function CreditCardFactory() { 

     function parseMessage(message) { 
      if (message.response) { 
       return message.response; 
      } 
     } 

     function CreditCard(value) { 
      angular.copy(value || {}, this); 
     } 

     CreditCard.$get = function(id) { 
      var value = this instanceof CreditCard ? this : new CreditCard(); 
      $http({ 
       method: 'GET', 
       url: '/creditcards/' + id 
      }).then(function(response) { 
       var data = response.data; 
       if (data) { 
        angular.copy(parseMessage(data), value); 
       } 
      }); 
      return value; 
     }; 

     CreditCard.prototype.$get = function(id) { 
      CreditCard.$get.call(this, id); 
     }; 

     return CreditCard; 

    } 

    return CreditCardFactory; 

}]); 

Następnie, w ramach funkcji kontrolera, wstrzyknąć fabrykę kart kredytowych tak, jak zasób $.

app.controller('CreditCardCtrl', function($scope, CreditCard) { 
    $scope.creditCard = CreditCard().get(3); 
}); 

To pozwala analizować reakcje swoich działań REST tak chcesz, a także pozwala na wdrożenie wszelkich działań, które chcesz. Na przykład: chciałem zapisać metodę na moich zasobach, która sprawdzi, czy obiekt ma właściwość id, zanim zdecyduje się użyć testu POST (tworzenie nowego zasobu, gdy nie jest dostępny identyfikator) lub PUT (aktualizacja istniejącego zasobu, gdy ważny identyfikator jest dostępny).

Umożliwia to również wdrożenie innego sposobu obsługi urządzenia JSON CSRF Vulnerability. Metoda angular.js jest wbudowana w $ http, ale funkcja REST API mojej firmy rozwiązuje ten problem, owijając tablice JSON w obojętny obiekt. Używam niestandardowego zasobu, takiego jak powyższy, do parsowania obojętnego obiektu.

+0

dzięki. Ja też myślałem o tym. – bsr

+0

To jest świetna odpowiedź, Brett, dzięki. Im więcej pracuję w magazynie '$ resource', tym bardziej znajduję chęć napisania niestandardowego opakowania na' $ http'. – quickshiftin

+0

używając tej metody, musisz zaimplementować własne metody save(), delete() itp., Poprawne? – JBCP