I see from your question (and from your SO tags) that you want to create a Rails-like controllers in AngularJS. Since both frameworks (Rails and AngularJS) share a similar MVC principle this is actually quite easy to accomplish.
Both frameworks allow you to instruct different routes to use the same controller.
In Rails, your usual index/show/new/edit/destroy methods (actions) are provided out of the box (with scaffolding). These default actions are mapped to different, well established routes and HTTP methods.
CRUD/List routes in Rails

Now, in AngularJS applications (or all SPAs for that matter) you need only a subset of these routes, because client-side routing understands only GET requests:
CRU/List routes in AngularJS
AngularJS natively does not provide a scaffolding mechanism that would generate all your CRUD routes for you. But nevertheless it provides you with at least two different ways of wiring up your CRUD/List routes with a single controller.
Option 1 (Using $location.path()
)
Using location.path() method you can structure your PhotosCtrl
to do different things depending on, well, location path.
Routes:
app.config(
[
'$routeProvider',
function ($routeProvider) {
$routeProvider
.when('/photos', {
templateUrl: 'photos/index.html',
controller: 'PhotosCtrl'
})
.when('/photos/new', {
templateUrl: 'photos/new.html',
controller: 'PhotosCtrl'
})
.when('/photos/:id', {
templateUrl: 'photos/show.html',
controller: 'PhotosCtrl'
})
.when('/photos/:id/edit', {
templateUrl: 'photos/edit.html',
controller: 'PhotosCtrl'
});
}
]
);
Controller:
app.controller('PhotosCtrl', [
'$scope',
'Photos', // --> Photos $resource with custom '$remove' instance method
'$location',
'$routeParams',
function($scope, Photos, $location, $routeParams){
if($location.path() === '/photos'){
// logic for listing photos
$scope.photos = Photos.query();
}
if($location.path() === '/photos/new'){
// logic for creating a new photo
$scope.photo = new Photos();
}
if(/\/photos\/\d*/.test($location.path())){ // e.g. /photos/44
// logic for displaying a specific photo
$scope.photo = Photos.get({id: $routeParams.id});
}
if(/\/photos\/\d*\/edit/.test($location.path())){ // e.g. /photos/44/edit
// logic for editing a specific photo
$scope.photo = Photos.get({id: $routeParams.id});
}
// Method shared between 'show' and 'edit' actions
$scope.remove = function(){
$scope.photo.$remove();
}
// Method shared between 'new' and 'edit' actions
$scope.save = function(){
$scope.photo.$save();
}
}
]);
These four ifs
makes the controller look a bit messy, but when replacing 4 different controllers with one, few conditionals are inevitable.
Option 2 (Using resolve property)
This option employes the resolve
property of the route configuration object to produce different 'action identifier' for different routes.
Routes:
app.config(
[
'$routeProvider',
function ($routeProvider) {
$routeProvider
.when('/photos', {
templateUrl: 'photos/index.html',
controller: 'PhotosCtrl',
resolve: {
action: function(){return 'list';}
}
})
.when('/photos/new', {
templateUrl: 'photos/new.html',
controller: 'PhotosCtrl',
resolve: {
action: function(){return 'new';}
}
})
.when('/photos/:id', {
templateUrl: 'photos/show.html',
controller: 'PhotosCtrl',
resolve: {
action: function(){return 'show';}
}
})
.when('/photos/:id/edit', {
templateUrl: 'photos/edit.html',
controller: 'PhotosCtrl',
resolve: {
action: function(){return 'edit';}
}
});
}
]
);
Controller:
app.controller('PhotosCtrl', [
'$scope',
'Photos',
'$routeParams',
'action'
function($scope, Photos, $routeParams, action){
if(action === 'list'){
// logic for listing photos
$scope.photos = Photos.query();
}
if(action === 'new'){
// logic for creating a new photo
$scope.photo = new Photos();
}
if(action === 'show')
// logic fordisplaying a specfiic photo
$scope.photo = Photos.get({id: $routeParams.id});
}
if(action === 'edit')
// logic for editing a specfic photo
$scope.photo = Photos.get({id: $routeParams.id});
}
// Method shared between 'show' and 'edit' actions
$scope.remove = function(){
$scope.photo.$remove();
}
// Method shared between 'new' and 'edit' actions
$scope.save = function(){
$scope.photo.$save();
}
}
]);
Both methods require using some conditionals in your controller, but the second method is at least a bit clearer to read, because the exact action is resolved inside the routing mechanism, which takes some logic off of your busy controller.
Of course, in any real-world application you'll probably have many more methods defined inside the controller, in which case your controller might get quite unreadable. These examples use a simple $resource instance (Phones
) which relies on a simple RESTfull backend API (Rails?).
But, when your view logic becomes complex you will probably want to employ Angular services/factories in order to abstract some of the code in your controllers.