2

I'm making a CRUD page using AngularJS, which will have an add/edit/delete function. So, my routes will be something like this:

/items (show a list of the items)
/items/add (show add item form)
/items/edit/:itemId (show edit item form)
/items/del/:itemId (Delete item)

It seems that I would have to define a different controller for each of these 4 routes. E.g, AddItemCtrl, EditItemCtrl, etc. However, that doesn't seem optimal since the AddItemCtrl and EditItemCtrl are going to share a good deal of their code. Rather than AddItemCtrl, EditItemCtrl, etc, I would rather have only one controller: ItemCtrl , and within my route, I'd rather specify if I want to call ItemCtrl.add(), ItemCtrl.edit(), etc.

Is there a way to accomplish this or something close to it?

Ali
  • 261,656
  • 265
  • 575
  • 769
  • You can use the same controller for both Edit and Add – Eric Zhang Aug 12 '13 at 21:02
  • I think you need to watch for route changes like illustrated [here](http://stackoverflow.com/questions/14765719/angularjs-how-to-watch-for-a-route-change). In particular do a $scope.$on('$routeChangeSuccess', handler); – Joe Minichino Aug 12 '13 at 21:03
  • @JoeMinichino Then I will be needlessly interferring with my `routes.otherwise()` method which is defined to redirect to `/dashboard` – Ali Aug 12 '13 at 21:04
  • Plus loading up the edit/add forms in the `ng-view` would be complicated with that method – Ali Aug 12 '13 at 21:06
  • Generally the routing of Angularjs is for handling page flow and the controller is for managing the scope. It is not like the API routing mapping to specific function to handle the specific request. – zs2020 Aug 12 '13 at 21:09
  • @sza So how would you recommend doing this? – Ali Aug 12 '13 at 21:10
  • 1
    The CRUD should be implemented using factory or $resource, and the routing should be handled by the web service API which is not a part of UI. AngularJS's MVC is like the UI layer of the SOA. – zs2020 Aug 12 '13 at 21:12
  • @sza But the UI to be displayed (list, add form, edit form) does depend on the route. – Ali Aug 12 '13 at 21:14
  • 1
    @ClickUpvote that should be just a function call in your controller, and the function calls Resource or Factory to talk to your SOA. You basically need to inject the Resource module in the controller – zs2020 Aug 12 '13 at 21:17
  • @sza I don't see how that helps me determine which UI to show depending on which link the user clicks at. – Ali Aug 12 '13 at 21:20

3 Answers3

1

For AngularJS, remember it is client side, so the url resource doesn't have to directly related to the CRUD operation. I would recommend thinking of the url route as the view, not the operation.

For example, I would use these:

/items (show a list of the items)   
/items/edit/:itemId (show edit item form)

I would not use these:

/items/add (show add item form)
/items/del/:itemId (Delete item)

The reason I would not use the urls above client side is that what would you display for a /items/add resource? It would probably be the /items list right? Same goes for the /items/del/:itemId

I would make two controllers. One that is an Items controller (i.e. a list of items) and an Item controller (i.e. a single item). Both should defer their functionality to a central service that manages Items. The service would allow CRUD operations, and calling any CRUD operations on a server that would probably use the routes as you have originally defined them.

As a side note, you could have an Items controller, ItemsEdit controller, ItemAdd controller, and ItemDelete controller. But you should keep your controller very thin. Basically just there to call ItemsService methods. Each of the controllers would just provide specific view functionality and defer any real work to the service.

Josh Petitt
  • 9,371
  • 12
  • 56
  • 104
1

Try https://github.com/angular-ui/ui-router, an excellent addition to Angular that makes it easy to map paths to views with hierarchical states that allow you to easily share code.

/items - use a deferred promise to resolve the items collection 
         and display a view
/items/add - display the add form (inherit /items state)
/items/:itemId - resolve a specific item and display it in the 
         view (inherit /items state)
/items/:itemId/edit - display the edit form for an item 
         (inherit /items:itemId state)

I would not provide an Url for deleting an item.

Ian Mercer
  • 38,490
  • 8
  • 97
  • 133
0

I ended up writing a directive and assigning click handlers for showing / hiding the appropriate forms.

Ali
  • 261,656
  • 265
  • 575
  • 769