Using bindToController with ControllerAs syntax in Angular

17 / Nov / 2015 by Heena Dhamija 0 comments

In an Angular application, when we use a controller as syntax we generally encounter isolated scope binding issues, controller’s scope is bound to ‘this’ reference. But how does it work while building directive with an isolated scope? We can create an isolated scope by adding an object to our directive definition that explains how every scope property is bound to our directive.

var testApp=angular.module("testControllerAs")

testApp.controller("TechnologyController", ["$scope", function ($scope) {
this.name = "Tech Department"
this.employees = 1
}])

testApp.directive('testDirectiveWithScope', function () {
return {
restrict: 'E',
scope: {employees: "="},
controller: 'TechnologyController',
controllerAs: 'ctrl',
template: '<input type="text" /> {{ctrl.name}} {{ctrl.employees}}',
};
})


<div ng-controller="TechnologyController as tech">
{{tech.employees}} //Output :1
<test-directive-with-scope employees="tech.employees"></test-directive-with-scope>
</div>

In above example, employees do not bind with scope of controller. When we change no. of employees then no. of employees do not change inside every “TechnologyController“. Scope is not working with controllerAs. To bind employees with scope we should add a watcher which watch employees input box when input box updates then its value also update in controller.

Like this:

testApp.controller("TechnologyController", ["$scope", function ($scope) {
this.name = "Tech Department"
this.employees = 1
$scope.$watch('employees', function (newValue) {
this.employees = newValue;
}.bind(this));
}])

Watcher will update employee value according to input box. But we need $scope for this, which is not correct.

Solution bindToController :

Angular introduces a new property to the directive definition object called bindToController. BindToController enables the inherited properties to be bound to the Controller without $scope object. When controller is instantiated, the initial values of the isolated scope bindings are available on this & future changes are automatically available.

<div ng-controller="TechnologyController as tech">
Employess: {{tech.employees}}
<input type="text" ng-model="tech.employees">
<test-directive-with-scope employees="tech.employees"></test-directive-with-scope>
</div>

testApp.controller("TechnologyController", ["$scope", function ($scope) {
this.name = "Tech Department"
this.employees = 1
}])

In Angular 1.3,when we set bindToController property to true with isolated scope that uses controllerAs, then it binds all the properties of controller.

testApp.directive('testDirectiveWithScope', function () {
return {
restrict: 'E',
scope: { employees: "="},
bindToController:true,
controller: 'TechnologyController',
controllerAs: 'ctrl',
template: '
Template :{{ctrl.name}} {{ctrl.employees}}'
};
})

Improvement in Angular 1.4, We can move all the property binding definition to bindToController & make it an object.

testApp.directive('testDirectiveWithScope', function () {
return {
restrict: 'E',
scope: {},
bindToController: {
employees: "="
},
controller: 'TechnologyController',
controllerAs: 'ctrl',
template: '
Template :{{ctrl.name}} {{ctrl.employees}}'
};
})

Building Intuitive Frontend Interfaces with AngularJS

FOUND THIS USEFUL? SHARE IT

Leave a Reply

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