Converting a directive to an AngularJS component

Loading

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.

FeatureDirective (restrict: 'E')Component (.component)
SyntaxComplex (requires linking, templates, controllers)Simplified
ReadabilityHard to maintainEasy to understand
BindingManual scope definitionUses bindings property
UpgradabilityHarder to migrateEasier 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

Leave a Reply

Your email address will not be published. Required fields are marked *