2012-10-04 24 views
9

que utilizan angular $resource para el servicio REST. Debido a la peculiaridad de mi respuesta get, no puedo usar $ resource service para la aplicación CRUD.

Creación de un nuevo objeto de trabajo (decir con tarjeta), smilar a:

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

Get también funciona:

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

embargo, la respuesta GET no es el objeto Card sí, pero aparte mensaje con él (objeto envoltorio)

{ message: ".....", 
    response: Card //object 
} 

así que cuando guardo la instancia retrie a través del recurso, envía el objeto contenedor (con el objeto Card modificado en el campo de respuesta). Esto probablemente sea correcto, pero mi servidor espera que el objeto de la Carta no sea el envoltorio. ¿Hay alguna forma de personalizar $ recurso para que envíe el objeto deseado? Desde el documento, parece que solo se pueden cambiar los parámetros de la url.

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

¿Puedes publicar un ejemplo completo en jsfiddle, o similar? En mi experiencia, para (simple) CRUD no es necesario crear un objeto nuevo como ese. ¿Qué sucede si simplemente accede a su recurso como $ scope.card = Card.get ({_ id: 1), donde Card es su servicio de recursos? Además, si le dice a su formulario cuál es su modelo, la instancia se llena automáticamente. – Narretz

+0

No creo que sus problemas estén en Angular. Suena casi como su implementación de REST en el lado del servidor tiene algunos problemas. No debe haber un mensaje adjunto. Es posible que desee verificarlo primero para asegurarse de que el cuerpo de la respuesta sea solo el objeto que estaba esperando. –

+0

El servidor de hecho está enviando un contenedor alrededor del objeto real. Aún así, ¿hay alguna manera de enviar solo el objeto cuando se envíe de vuelta al servidor (POST) – bsr

Respuesta

17

También he tenido problemas con la implementación estándar en el módulo $ resource. Por un tiempo acabo de hacer ediciones en mi propia copia local del archivo $ resource, pero descubrí que todavía no estaba satisfecho con la forma en que implementaron los recursos REST. Necesitaba más flexibilidad de la que me ofrecieron.

El módulo estándar $resource es sólo un envoltorio de fábrica alrededor de $ http. Si reduce el código en el módulo $ resource, puede crear su propia implementación personalizada con bastante facilidad.

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; 

}]); 

Luego, dentro de la función de su controlador, inyecte la fábrica de CreditCard tal como lo haría con $ resource.

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

Esto le permite analizar las respuestas de sus acciones REST tantas veces como quiera, y también le permite implementar cualquier acción que desee. Por ejemplo: quería un método de guardado en mis recursos que verificara si el objeto tenía una propiedad de id. Antes de elegir usar una POST (creando un nuevo recurso cuando no hay una id disponible) o una PUT (actualizando un recurso existente cuando identificación válida está disponible).

Esto también permitiría a poner en práctica una forma diferente de manejar la JSON CSRF Vulnerability. El método angular.js está integrado en $ http, pero la API REST de mi empresa corrige este problema al envolver las matrices JSON en un objeto ficticio. Utilizo un recurso personalizado como el de arriba para analizar el objeto ficticio.

+0

gracias. Yo también estaba pensando en las líneas. – bsr

+0

Esta es una gran respuesta Brett, gracias. Cuanto más trabajo con el stock '$ resource', más encuentro el deseo de escribir un contenedor personalizado encima de' $ http'. – quickshiftin

+0

usando este método, necesita implementar sus propios métodos save(), delete() etc., ¿correcto? – JBCP