flapas
flapas

Reputation: 583

AngularJS - Access isolate scope when using "controller as" syntax in directive

I was reading a very interesting resource and I stumbled across this piece of code:

angular
    .module('app')
    .directive('myExample', myExample);

function myExample() {
    var directive = {
        restrict: 'EA',
        templateUrl: 'app/feature/example.directive.html',
        scope: {
            max: '='
        },
        link: linkFunc,
        controller: ExampleController,
        controllerAs: 'vm',
        bindToController: true // because the scope is isolated
    };
    return directive;

    function linkFunc(scope, el, attr, ctrl) {
        console.log('LINK: scope.min = %s *** should be undefined', scope.min);
        console.log('LINK: scope.max = %s *** should be undefined', scope.max);
        console.log('LINK: scope.vm.min = %s', scope.vm.min);
        console.log('LINK: scope.vm.max = %s', scope.vm.max);
    }
}

ExampleController.$inject = ['$scope'];

function ExampleController($scope) {
    // Injecting $scope just for comparison
    var vm = this;
    vm.min = 3;
    console.log('CTRL: $scope.vm.min = %s', $scope.vm.min);
    console.log('CTRL: $scope.vm.max = %s', $scope.vm.max);
    console.log('CTRL: vm.min = %s', vm.min);
    console.log('CTRL: vm.max = %s', vm.max);
}

What got most of my curiosity was the

console.log('LINK: scope.max = %s *** should be undefined', scope.max);

in the directive's link function. I don't understand why scope.max should be undefined. vm is defined in the controller, so why does the max attribute – which is directly defined in the directive's isolate scope – must be accessed through it on the link function? Is it related to using the controller as syntax on the directive?

Upvotes: 2

Views: 2268

Answers (1)

Matt Herbstritt
Matt Herbstritt

Reputation: 4862

I think it's the bindToController option that is the important bit here. It binds the isolate scope variables to the controller rather than the scope. Thus, there is no max property on the scope, just on the controller instance. This controller instance is then assigned to a property on the $scope when you use controllerAs so, in your example, you would see vm as a property on your $scope object if you were to log it in the console for example.

You can read more about bindToController in the $compile section in the docs: https://docs.angularjs.org/api/ng/service/$compile

Upvotes: 3

Related Questions