AngularJS – Directive vs Service vs Controller

angularjs

I am about to start implementing a change request on my companies internal website, that will check a bunch of fields and highlight them if they match certain guidelines. For example, if the date of birth is today, that field will be outlined and the tooltip will say "Wish them a happy birthday!".

The specs ask for this to be loaded after the rest of the page is done rendering, so it won't increase the load time. Since I am new to angularJS, I'm not sure of the 'proper' ways this should be done.

Issues:

Since this includes adding borders and images and title attributes (DOM manipulation), it seems I should be using a directive.

However, this won't be reusable or 'short' like most directives seem to be.

Half of the data I need to check will be returned in the original call on page load, so I would like to save that and not waste another call getting it again, which makes me think a service would be nice for storing all that data.

I do know how to do this all in the controller, but that is bad bad code 😛

Any ideas on the best way this could be done? Basically, I will need an http call to check all the data, which will return an object with bool values for each type of 'Call Out' I need to do. Then I'll run through this list and if the value is true, add a border, image, and tooltip text.

I'm not sure if this question is clear enough, so if you want me to add some details, please ask. Thank you!

Best Answer

You're right, there's many options at play.

A controller is a good place to start writing something new in angular. Tying a controller to a piece of markup lets you use angular's already existing library of directives with angular's existing services.

After a very short while of living with this, you'll realize your controller has gotten too large. Well now its time to refactor. Here's the general guidelines I tend to follow.

  • Controllers: controllers attach and manage values/functionality tied to the $scope. Ultimately $scope tends to be heavily presentation driven. IE its a view model.
  • Services: services tend to tie in infrastructure, backend, or other browser features
  • Directives: directives allow you to integrate with DOM events/functionality not handled by existing handlers.

So you'll want to push code in one of three directions:

  1. Code from my controller is really logically another piece of presentation data/logic and should be split into another controller. Note when working with items on $scope, its best to segregate parts that each controller is responsible for into their own objects on $scope. For example $scope.creditCard.[blah] for one controller vs $scope.billingAddress.[blah] for another controller. This helps prevent issues with angular's use of prototype inheritance on $scope.

  2. Code from my controller is a piece of application infrastructure or utility code, that may need to be shared through the app, and should be split off into a service

  3. Code from my controller is concerned heavily with presentation/DOM organization, and therefore should be split off into its own directive

An example of 1. might be to handle entering/validating credit card separate from the rest of the payment form. You'd have a bunch of credit card logic in a controller separate from the logic for letting users input addresses, so they'd be logically separate controllers.

An example of 2 might be to move the part that communicates with the credit card backend service to accept/decline payment. Or another example might be a module that talks to the backend to handle the user creation API.

An example of 3 might be to create some sort of auto-tab functionality that moves the cursor between the 4 edit boxes after the 4 numbers are entered for a credit card.

Split up your app accordingly.

Related Topic