This article represents top 10 best practices that one may want to apply while creating custom directives. Please feel free to comment/suggest if I missed to mention one or more important points. Also, sorry for the typos.
Following is listed the best practices for creating custom directives:
- Naming Convention: Prefer using two or three letter prefix (except ng) while naming directives to avoid collision with future HTML releases. Using “ng” as prefix might collide with AngularJS OOTB directives in future.
- Directive Definition Object (DDO): Prefer returning DDO rather than a function.
- TemplateUrl Usage: Prefer storing HTML template code in a seperate file and assign the path to templateUrl variable.
- Attribute vs Element: Whether to create custom directive as an attribute or an element is tricky. If the need is to create a component with core behavior and possibility to decorate the component with additional behavior in future, you would want to make the directive as element (E). However, if the need is to decorate existing element with some custom behavior, you could create dirrective of attribute (A) type.
- Isolate Scope: If the need is to reuse the component (directive) throughout your app, consider creating isolate scopes using scope option. The concept of isolate scope is used to separate the scope inside a directive from the scope outside.
- Clean-up function: Consider defining clean-up function by registering an event, element.on( ‘$destroy’, …). It is a good practice to remove event listeners once the ‘$destroy’ event is broadcasted, to avoid instances of memory leaks. Listeners registered to scopes and elements are automatically cleaned up when they are destroyed.
- Controller vs Link function: It is often confusing to beginners on when to use controller function and when to define link function within the custom directive. Thumb rule is use controller function when there is a need to expose APIs to other directives. In other cases, one could use link function.
- DOM Manipulation: Use the “link” option if there is a need to modify the DOM.
- Access to Outside Scope Object: If there is a need for directives’ content to access content from outer scope object (not defined within directive), one may want to use “transclude: true”.
- Usage of @attr, =attr, &attr:Following is details related with @attr, =attr and &attr:
- @attr:@ binds a directive scope property to the evaluated value of the DOM attribute. If you use name=name1 or name=”name1″, the value of DOM attribute “name” is simply the string name1. If you use name=”{{name}}”, the value of the DOM attribute “name” is the interpolated value of {{name}}. Simply speaking, with @attr, one can bind a isolated scope property to a DOM attribute. This sets up a one-way databinding from the parent scope to the isolated scope. If the parent scope changes, the isolated scope will reflect that change, but not the other way around.
- =attr:= binds a directive scope property to a parent scope property. So with =, you use the parent scope property name as the value of the DOM attribute. And if isolated scope property changes, then it will update the property that exists in parent scope.
- &attr:The & symbol is used to to call an expression on the parent scope from the isolated scope.
I have prepared an example to illustrate Custom Directive creation, and you can find it here: http://jsfiddle.net/arifkhoja/VJ94U/1921/
Arif Khoja is a Developer. He is a Javascript Enthusiatic who loves logical programming and has first hand experience in building a cutting edge internet product using Angular. He is also an open source freak and keen about learning and sharing. He writes Javascript both frontend and backend. He loves learning and sharing tech all the time. He also has a hands on experience in SEO and writes articles about latest emerging technologies.