Reputation: 1388
Earlier today I asked about how to call one controller from another, I was having a lot of trouble with what functions should be where etc. This got me thinking on the bigger picture, on how I should build my project, to be as clean and logical as possible.
My application works against a SharePoint server, I have service.js files with $resource
factorys to communicate with SharePoint, an example:
ItemService.js
myApp.service('ItemService', function ($q, Item) {
this.getItem = function (id){
var deferred = $q.defer();
setTimeout(function() {
var item = Item.get({ID: id }, function(){
deferred.resolve(item.d.results[0]);
}, function(error){
deferred.reject(error);
});
}, 1000);
return deferred.promise;
};
});
myApp.factory('Item', function($resource) {
return $resource("serverURL/lists/getByTitle('Items')/items", {}, {
get: {
method: 'GET',
headers: { "Accept": "application/json; odata=verbose" },
url: "serverURL/lists/getByTitle('Items')/items?$select=&$filter=ID eq :ID"
}
});
});
To use these services I have a controller file, example:
ItemController.js
angular.module('myApp').controller('ItemController', function ($scope, $modal, $log, ItemService) {
$scope.loadItem = function(id){
var promise = ItemService.getItem(id);
promise.then(function(item){
$scope.viewItem(item);
}, function(err){console.log(err);})
};
});
This was example of the controller and service files for the sharepoint list Items
, I also have one controller and one service for Tasks
, as well as the main controller, AppController
.
Are my extra controllers unnecessary? Should I just inject my services into my AppController, and write my function there instead?
My problem is that when my project gets bigger, this way is easier to read and understand, but code gets more complicated since controllers would have to communicate a lot. On the other hand, if I inject my Services into my AppController it would be hard to read, but still work as intended.
Upvotes: 2
Views: 150
Reputation: 1013
I like to keep my controllers responsible for a single thing.
For example, I have a project management app. On the project page there is a search on the left side and the selected project on the right. I have a controller for each because they are unrelated enough that I can change one without affecting the other.
The selected project display has three tabs, one for general info, one for a list of tasks and another for a list of contacts. I have a controller for each tab. Because they all inject the project service they all have access to the same project object when they instantiate, and this keeps each controller focused.
When the user adds a task or a contact I display a modal with a list of available tasks or contacts. A separate controller handles that list and modal.
It's the single responsibility principle and it works well to keep your code clean, even if it means having a few more controllers. It also means my stuff is reusable. If I want to have one of those modals on a different entity I can, because the modal has no concept of the project, it only knows it's doing a search for tasks or projects and returning the selected ones to its caller. If I had one big controller for everything I would have to write that code again.
Upvotes: 1
Reputation:
If your app is growing, do break it out into multiple controllers. In my last project in public/js/media folder, I had media.js (the controller), media.service.js, media.tmpl.html and _media.scss.
A simpler way is to break them up by main views (you may have nested views or templates as well).
As far as injecting services go, I like to do as much work as possible in the service and I restrict the actual service to dealing with external data and the factory deals with local/returned data being passed around, parsed or replicated.
I structure my API calls the way you've done with just attaching a promise on the end of the API call from the service. This will keep your controllers much cleaner as your code expands.
Upvotes: 1