Lets talk about best practices and roles in AngularJS. A controller is the middle man.
Its main role is to talk to the Service to get the model and then make sure this model is available to our presentation layer(html).
Even in large applications, the controller should be small, compact and dumb!
Dom Manipulations should not exist in controllers, services or anywhere else but in directives.
This came up today. We have two products with its own results list controller.
productAResultsCtrl.coffee and productBResultsCtrl.coffee were both presenting this code:
This is meant to hide a search bar with advanced options and if the user clicks on a button we display all the options with a classic jquery slide effect.
This works but…
It is not reusable
It is not testable
It include css hard coded selectors dependencies
So in order to resolve these problems, we should always:
write a directive for dom manipulation
the directive should not have dependencies on other html blocks or scope’s parents objects
the directive should not have any hard coded css selector
We are going to write a directive to be applied in the div that should slide down or up based on an external variable.
To avoid dependency problems, we are going to pass this variable as a parameter. We dont care who changes this variable.
We only care to react when the variable changes.
Our directive should look something like this:
We use ‘data-‘ prefix to make sure html validates and we do not cause IE7, 8 browsers to go into quirks mode. Very Important!!!!
We use ‘my-‘ prefix to determine this is a custom directive that belongs to our team.
Lets write the code for this. As always the test comes first:
We have created two tests where after compiling the code, our directive applies slideDown or slideUp.
Based on jquery’s documentation the divs’ height gets primarily affected.
We take this fact so as to evaluate the success of our directive.
Now lets write the directive
So now on both productAResults.html and productBResults.html we say
And we remove the jquery dom maniuplations out of our controllers.
Now we have a reusable, independent, tested directive.