![]()
With the introduction of AngularJS 1.5+, components were introduced to simplify directives and promote a component-based architecture. If you’re working with older custom directives, it’s best to convert them into components for better readability, maintainability, and future migration to Angular 2+.
1. Why Convert a Directive to a Component?
Directives can be complex and require multiple configurations. Components make the same functionality simpler and follow a structured approach.
| Feature | Directive (restrict: 'E') | Component (.component) |
|---|---|---|
| Syntax | Complex (requires linking, templates, controllers) | Simplified |
| Readability | Hard to maintain | Easy to understand |
| Binding | Manual scope definition | Uses bindings property |
| Upgradability | Harder to migrate | Easier to migrate to Angular 2+ |
2. Converting a Simple Directive to a Component
Directive Example
Here’s a simple directive that displays a user’s name.
app.directive('userCard', function() {
return {
restrict: 'E',
scope: {
name: '@'
},
template: '<p>User: {{ name }}</p>'
};
});
Converted to Component
app.component('userCard', {
bindings: {
name: '@'
},
template: '<p>User: {{$ctrl.name}}</p>'
});
Simpler
No need to define restrict: 'E'
Uses bindings instead of scope
3. Converting a Directive with a Controller
Directive with Controller
app.directive('userProfile', function() {
return {
restrict: 'E',
scope: {
user: '='
},
template: `
<h3>{{ user.name }}</h3>
<p>Age: {{ user.age }}</p>
`,
controller: function($scope) {
$scope.greet = function() {
alert('Hello ' + $scope.user.name);
};
}
};
});
Converted to a Component
app.component('userProfile', {
bindings: {
user: '='
},
template: `
<h3>{{$ctrl.user.name}}</h3>
<p>Age: {{$ctrl.user.age}}</p>
<button ng-click="$ctrl.greet()">Greet</button>
`,
controller: function() {
this.greet = function() {
alert('Hello ' + this.user.name);
};
}
});
Uses bindings instead of scope
Uses $ctrl instead of $scope
More readable and structured
4. Handling Lifecycle Hooks ($onInit, $onChanges)
Old Directive (link function)
app.directive('welcomeUser', function() {
return {
restrict: 'E',
scope: {
name: '@'
},
template: '<p>Welcome, {{ name }}</p>',
link: function(scope) {
console.log('Directive initialized with', scope.name);
}
};
});
Converted to Component (Using $onInit)
app.component('welcomeUser', {
bindings: {
name: '@'
},
template: '<p>Welcome, {{$ctrl.name}}</p>',
controller: function() {
this.$onInit = function() {
console.log('Component initialized with', this.name);
};
}
});
Uses $onInit instead of link
Uses $ctrl for clarity
5. Handling Events (& Binding)
Directive with Event Callback
app.directive('clickMe', function() {
return {
restrict: 'E',
scope: {
onClick: '&'
},
template: '<button ng-click="onClick()">Click Me</button>'
};
});
Converted to Component
app.component('clickMe', {
bindings: {
onClick: '&'
},
template: '<button ng-click="$ctrl.onClick()">Click Me</button>'
});
Uses & binding for parent-to-child event communication
6. Passing Data with One-Way Binding (<)
Old Directive
app.directive('userInfo', function() {
return {
restrict: 'E',
scope: {
user: '='
},
template: '<p>Name: {{ user.name }}</p>'
};
});
Converted to Component (Using < Binding)
app.component('userInfo', {
bindings: {
user: '<' // One-way binding
},
template: '<p>Name: {{$ctrl.user.name}}</p>'
});
Uses one-way binding (<) instead of two-way (=)
Improves performance and prevents accidental modifications
