10/22/16

What is bindToController using for in angularjs?

If you start a new plunker by going to new -> angularjs -> 1.5.x you will get a starter template that attaches "name" property to the controller :


app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
});

and displays it in the template :

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>
  </body>

controllerAs

Actually the more recommended way (look at john papa style guide) to attach some properties and methods to the controller - is by using controllerAs syntax:


app.controller('MainCtrl', function() {
  var ctrl = this;
  ctrl.name = 'World';
});

and the template should now be:

  <body ng-controller="MainCtrl as ctrl">
    <p>Hello {{ctrl.name}}!</p>
  </body>

(ctrl is recommended name to use in the controllerAs syntax by angular guys)

The problem with directives

When writing directives which has their own controllers we may use the controllerAs syntax as well:


app.directive('doSomething', doSomething);
function doSomething() {
  return {
    restrict: 'E',
    replace:true,
    scope:{}, //<--isolated scope
    template:'<button ng-click="ctrl.clickBtn()">click here</button>',
    controllerAs:'ctrl',
    controller: function() {
      var ctrl = this;
      ctrl.name = 'koko';
      ctrl.clickBtn = function() { 
        alert(ctrl.name);  //<--will alert 'koko'
      }
    }
  };
}

But what happens when we need the 'name' property to be passed from the outer scope, like below?

  ...
  scope:{name:'='}
  ...

How we make the controller to know about its new property?
Thats what the bindToController setting in the directive configuration are responsible for - to bind the outer scope members to the controller of directive:

 app.directive('doSomething', doSomething);
 function doSomething() {
  return {
    restrict: 'E',
    replace:true,
    scope: {
      name: '='
    },
    template:'<button ng-click="ctrl.clickBtn()">click here</button>',
    controllerAs:'ctrl',
    bindToController: true, //<-- HERE
    controller: function() {
      var ctrl = this;
      ctrl.clickBtn = function() { 
        alert(ctrl.name);   //<--will alert 'World'
      }
    }
  };
}


full code at this plunkr

Components

Since angular 1.5 introduced the Component method - we can take advantage of using the components to achieve the similar behavior:


app.component('somethingNewer', {
  bindings: {
    name: '='
  },
  template:'<button ng-click="ctrl.clickBtn()">click here</button>',
  controllerAs:'ctrl',
  controller: function() {
      var ctrl = this;
      ctrl.clickBtn = function() { 
        alert(ctrl.name); 
      }
  }
});

This code doing the same thing, but it shorter and its more like angular2
P.S.
controllerAs property if not specified - defined by default as $ctrl.
Hope you have fun reading...

No comments:

Post a Comment

Getting started with docker

It is very simple to get started usig docker. All you need to do-is download the docker desktop for your system Once you get docker syste...