Reputation: 1602
I have an Angular JS app that is communicating with a REST API. The app has an admin part that let a user create, read, update and delete a resource.
There's several different resources, one partial per resource where I define each member as an input field of some sort. I have created a directive that creates a two way binding for whats common for the templates.
I have also created a ngResource for each of my resources.
Now to my problem. I have the controller for one resource working, and it mostly contains just functions that are called directly from the partials (e.g submit() ), and communicates with the ngResource.
The code itself can, with a few exceptions, be copied to all of the other controllers and just change the resource name. This is what I want to avoid.
How can I create an abstract ParentCtrl and somehow inject the resource I need at that time? Is this testable? Is this a bad approach of the problem?
Normally I would have tried to abstract a model instead of a controller, but I can't really see how in this case.
Edit: Added code
Resource:
angular.module('experienceServices', ['ngResource'])
.factory('Experience', function($resource){
return $resource('/api/experience/:id',
{'id': '@_id'}, {edit: { method: 'PUT' }});
});
Controller:
App.controller('ExperienceCtrl', function( $scope, Experience ) {
$scope.resources = [];
$scope.currentItem = {};
$scope.updateResources = function(){
$scope.resources = Experience.query();
};
$scope.findById = function(id){
for (var i = 0; i < $scope.resources.length; i++){
if ($scope.resources[i]._id === id){
return $scope.resources[i];
}
}
};
$scope.showItem = function(id){
$scope.currentItem = findById(id);
};
$scope.create = function (experience){
Experience.save(angular.copy(experience), function(){
$scope.updateResources();
});
};
$scope.editItem = function (experience){
var item = angular.copy(experience);
if (!item.hasOwnProperty('_id')){
alert('Can not modify non existing item');
}
Experience.edit(item, function(res){
$scope.updateResources();
});
};
$scope.edit = function(id){
$scope.experience = $scope.findById(id);
};
$scope.del = function(id){
Experience.remove({ id: id }, function(){
$scope.updateResources();
});
};
$scope.updateResources();
});
Directive:
App.directive('resources', function (){
return {
scope: {
list: '=',
display: '@',
edit: '&',
del: '&'
},
template: '<div ng-repeat="elem in list">Name: {{ elem[display] }}' +
' <button ng-click="edit({ item: elem._id })">Edit</button> ' +
' <button ng-click="del({ item: elem._id })">Delete</button> ' +
'</div>'
};
});
Upvotes: 0
Views: 284
Reputation: 17803
what about wrapping your entire API to a service and accessing it from the controllers ? you can pass the resource type as an argument to the functions
Upvotes: 1