angularjs resource save example
¿Es posible utilizar plantillas de URL parametrizadas con el servicio angular $ http? (2)
Estoy usando $ resource para mi API RESTful y me encanta la plantilla de URL parametrizada, por ejemplo, ''api/clients/:clientId''
Esto funciona muy bien para las operaciones de CRUD. Sin embargo, algunos de mis api son solo informes o puntos finales de solo lectura sin la necesidad de un tratamiento completo de REST. Sentí que era excesivo usar $ resource para ellos y en su lugar usé un servicio de datos personalizado con $ http.
El único inconveniente es que pierdo las plantillas de URL parametrizadas. Me encantaría definir una url como ''api/clients/:clientId/orders/:orderId''
y simplemente pasar { clientId: 1, orderId: 1 }
. Me doy cuenta de que puedo construir la url dinámicamente, pero esperaba que $ http fuera compatible con la plantilla parametrizada y aún no la he encontrado.
Todo lo mejor
ACTUALIZACIÓN 7/5
La palabra que faltaba en mis búsquedas es ''Interpolar''. Más información aparece cuando busco ''interpolación de url en $ http angular''. La respuesta corta parece ser ''No'' $ http no admite la interpolación de URL. Sin embargo, hay algunas maneras bastante fáciles de lograr esto.
1. Utilice $ interpolar:
Documentación para $interpolate
here
var exp = $interpolate(''/api/clients/{{clientId}}/jobs/{{jobId}}'', false, null, true);
var url = exp({ clientId: 1, jobId: 1 });
2. Escribe tu propia función de interpolación de url
Ben Nadel tiene una excelente publicación sobre este tema exacto here .
3. Robar la funcionalidad del recurso angular
Echa un vistazo a setUrlParams en Route.prototype in angular-resource.js . Es bastante sencillo.
Ejemplo de servicio de datos usando $ interpolar
(function () {
''use strict'';
var serviceId = ''dataservice.jobsReports'';
angular.module(''app'').factory(serviceId, [''$http'', ''$interpolate'', function ($http, $interpolate) {
var _urlBase = ''http://localhost:59380/api'';
var _endPoints = {
getJobsByClient: {
url: ''Clients/{{clientId}}/Jobs'',
useUrlInterpolation: true,
interpolateFunc: null
}
};
// Create the interpolate functions when service is instantiated
angular.forEach(_endPoints, function (value, key) {
if (value.useUrlInterpolation) {
value.interpolateFunc = $interpolate(_urlBase + ''/'' + value.url, false, null, true);
}
});
return {
getJobsByClient: function (clientId) {
var url = _endPoints.getJobsByClient.interpolateFunc({ clientId: clientId });
return $http.get(url);
}
};
}]);
})();
Para evitar que esto quede "sin respuesta" cuando se ha respondido ...
1. Utilice $ interpolar:
Documentación para $interpolate
here
var exp = $interpolate(''/api/clients/{{clientId}}/jobs/{{jobId}}'', false, null, true);
var url = exp({ clientId: 1, jobId: 1 });
2. Escribe tu propia función de interpolación de url
Ben Nadel tiene una excelente publicación sobre este tema exacto here .
3. Robar la funcionalidad del recurso angular
Echa un vistazo a setUrlParams en Route.prototype in angular-resource.js . Es bastante sencillo.
Ejemplo de servicio de datos usando $ interpolar
(function () {
''use strict'';
var serviceId = ''dataservice.jobsReports'';
angular.module(''app'').factory(serviceId, [''$http'', ''$interpolate'', function ($http, $interpolate) {
var _urlBase = ''http://localhost:59380/api'';
var _endPoints = {
getJobsByClient: {
url: ''Clients/{{clientId}}/Jobs'',
useUrlInterpolation: true,
interpolateFunc: null
}
};
// Create the interpolate functions when service is instantiated
angular.forEach(_endPoints, function (value, key) {
if (value.useUrlInterpolation) {
value.interpolateFunc = $interpolate(_urlBase + ''/'' + value.url, false, null, true);
}
});
return {
getJobsByClient: function (clientId) {
var url = _endPoints.getJobsByClient.interpolateFunc({ clientId: clientId });
return $http.get(url);
}
};
}]);
})();
Para las plantillas de URL, hay una recomendación claramente definida: RFC 6570
Puede encontrar una implementación en Github: bramstein/url-template
Es bastante simple. Aquí hay un servicio AngularJS que utiliza una biblioteca que implementa el estándar RFC 6570 :
var app=angular.module(''demo'',[]);
app.service(''UserStore'',function () {
var baseUrl=urltemplate.parse(''/rest/v1/users{/_id}'');
return {
load:function(id){
return $http.get(baseUrl.expand({_id:id}));
},
save:function (profile) {
return baseUrl.expand(profile);
//return $http.post(baseUrl.expand(profile),profile);
},
list:function (id) {
}
}
});
app.controller(''demoCtrl'',function(UserStore){
this.postUrlOfNewUser=UserStore.save({name:"jhon"});
this.postUrlOfExistingUser=UserStore.save({_id:42,name:"Arthur",accessory:"towel"});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdn.rawgit.com/bramstein/url-template/master/lib/url-template.js"></script>
<div ng-app="demo">
<div ng-controller="demoCtrl as ctrl">
<div>New user POST URL: {{ctrl.postUrlOfNewUser}}</div>
<div>Existing user POST URL: {{ctrl.postUrlOfExistingUser}}</div>
</div>
</div>
<script>
</script>
Como puede ver, el estándar incluso maneja el componente PATH opcional. ¡Es una brisa!
Y también puedes usar "." o ";" - Para notación matricial e incluso expandir cadenas de consulta!