I have a bunch of data types : users, products, categories. I have a single view/controller for CRUDing each type of data. Therefore, my view allows to create an item, it displays a list, and for each item you can edit and update, or delete it.
The controller manages all UI interactions. For example, when an item is deleted, the user has access to a cancel button for several seconds. Into the controller all CRUD operations are done through services.
angular.module('myApp').controller(
'UsersManagerController',
function UsersManagerController($scope, $timeout, userService) {
$scope.deleteUser = function(user) {
user.deleting = true;
user.deletionCancelable = true;
user.deletePromise = $timeout( function() {
user.deletionCancelable = false;
userService.deleteUser(user.id);
}, 2000);
};
$scope.isUserDeleting = function(user) {
return user.deleting;
}
$scope.cancelDelete = function(user) {
$timeout.cancel(user.deletePromise);
user.deletePromise = null;
user.deleting = false;
user.deletionCancelable = false;
}
Now, I would like to avoid repeating this controller code for each type of data (products, categories...), and only write several views. It means I would like a single controller which could receive dynamically a service exposing the CRUD methods for a particular data type. I have managed to do this, using the $injector. But I don't know how to give the controller the service name from the view. I have tried this :
<div ng-controller="ItemsManagerController" ng-init="setItemService('userService')">
And into the controller :
var _crudService;
$scope.setCrudService = function(serviceName) {
_crudService = $injector.get(serviceName);
}
But the setCrudService() is called at runtime, managed by the AngularJs binding. It means I cannot known exactly when it will be called, and some other methods of my controller are called before, trying to use the service that has not been set yet.
Does anyone knows how to do this ?
Maybe my design has a flaw ?
UPDATE :
I found a solution : scope inheritance.
<div ng-controller="UsersManagerController">
<div ng-controller="ItemsManagerController">
<div ng-repeat="user in items">
<span ng-click="deleteItem(user.id)">Remove {{user.name}}</span>
</div>
</div>
</div>
1) UsersManagerController will be initialized first.
2) ItemsManagerController scope will inherit UsersManagerController scope.
angular.module('myApp').controller('UsersManagerController',
['$scope', 'userService', function UsersManagerController($scope, userService) {
$scope.crudService = userService;
}]);
angular.module('myApp').controller('ItemsManagerController',
['$scope', function ItemsManagerController($scope) {
$scope.deleteItem = function(itemId) {
$scope.crudService.delete(itemId);
}
$scope.items = crudService.getItems();
}]);
It works, but I have to write a controller for each data type. I am still looking for a more elegant solution.