We are busy upgrading our projects to Angular 1.5 in preparation for Angular 2.
Here is a quick walkthrough of converting a basic angular directive to component.
Angular Directive
1 2 3 4 5 6 7 8 9 10 11 12 13 | angular.module(‘app’).directive(‘contactForm’, function() { return { email: ‘=?’, name: ‘@’, surname: ‘@’ }, controller: function($scope, sendEmail) { $scope.send = function() { sendEmail.send($scope.email, $scope.name, $scope.surname); }; }, templateUrl: ‘views/templates/contactForm.html’ }); |
I have, in this example, made email a two way data binding, and name and surname just strings.
Template
Contact Form template
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <div class="form-wrapper"> <form> <p> <label$gt;Email</label> <input type=“text” name=“email” ng-model="email" /> </p> <p> label>Name</label> <input type=“text” name=“name” ng-model=“name /> </p> <p> <label>Surname</label> <input type=“text” name=“surname” ng-model=“surname” /> </p> </form> </div> |
Calling the directive in another view:
Directive bindings:
- @ String
- & One-way Binding
- = Two-way Binding
Component
Step 1:
Replace “.directive” with “.component”
Step 2:
Don’t pass a function as the second argument, pass an object with fields
You should now have
1 2 3 | angular.module(‘app’).component(‘contactForm’, { … }); |
Note the { … } instead of the function() {…}
Step 3:
Bind variables using “bindings: { .. }” instead of “scope: { … }”
You should now have
1 2 3 4 5 6 7 | angular.module(‘app’).component(‘contactForm’, { bindings: { email: ‘=?’, name: ‘@’, surname: ‘@’ } }); |
Component binding types:
- = Two-way Binding
- < One-way Binding
- @ String
- & Callbacks (to output to parent scope)
Step 4:
Add controller, similar to directives, except you no longer pass in $scope. The variables bind on “$ctrl” the default value for controllerAs.
You can assign controllerAs to any value, but for this example it is unnecessary.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | angular.module(‘app’).component(‘contactForm’, { bindings: { email: ‘=?’, name: ‘@’, surname: ‘@’ }, controller: function(sendEmail) { var $ctrl = this; $ctrl.send = function() { sendEmail.($ctrl.email, $ctrl.name, $ctrl.surname); } }, templateUrl: "/path/to/template/feature.template.html" }); |
Note
1 | var $ctrl = this; |
Explicitly give $ctrl the controller’s scope.
Replace $scope with $ctrl. In the template you will have to reference each variable with $ctrl. Eg {{$ctrl.email}}
Contact Form template
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <div class="form-wrapper"> <form> <p> <label$gt;Email</label> <input type=“text” name=“email” ng-model="$ctrl.email" /> </p> <p> label>Name</label> <input type=“text” name=“name” ng-model=“$ctrl.name" /> </p> <p> <label>Surname</label> <input type=“text” name=“surname” ng-model=“$ctrl.surname” /> </p> </form> </div> |