1

Directive scope values(initialValue and title) are undefined in my controller function - counterController. It prints initialValue if I define it like {{ counterCtrl.initialValue }} in app_counter.directive.html, but undefined in counterController function.

app_counter.directive.js

'use strict';

module.exports = function (app) {
    app.directive('appCounter', appCounter)
};

function appCounter() {
    let directive = {
        restrict: 'EA',
        template: require('./app_counter.directive.html'),
        scope: {
            initialValue: '=',
            title: '@'
        },

        controller: counterController,
        controllerAs: 'counterCtrl',
        bindToController: true
    };

    return directive;
}

function counterController() {
    let vm = this;

    vm.counter = vm.initialValue;
    vm.increment = increment;
    vm.decrement = decrement;

    function increment() {
        vm.counter += 1;
    }

    function decrement() {
        vm.counter -= 1;
    }
}

app.js

'use strict';

const angular = require('angular');
const app = angular.module('app', []);

require('./app_counter/app_counter.directive')(app);

app_counter.directive.html

<div class="counter">
    <div>Current value {{counterCtrl.title}}: {{ counterCtrl.counter }}</div>
    <button type="button" ng-click="counterCtrl.decrement()">Decrement</button>
    <button type="button" ng-click="counterCtrl.increment()">Increment</button>
</div>

index.html

<div id="app" ng-app="app">
    <app-counter title="hello" initial-value="10"></app-counter> 
</div>
0

1 Answer 1

2

You need to access them with $scope (as they are) inside your controller instead using your controller instance object (this) directly.

function counterController($scope) {
    let vm = this;

    vm.counter = $scope.initialValue;
    vm.increment = increment;
    vm.decrement = decrement;

    function increment() {
        vm.counter += 1;
    }

    function decrement() {
        vm.counter -= 1;
    }
}

>> Demo fiddle


By using bindToController:

You can achieve the same by using bindToController which is available since AngularJS v1.3:

myApp.directive('myDirective', function () {
    return {
      restrict: 'A',
      scope: true,
      controllerAs: 'counterCtrl',
      bindToController: {
        initialValue: '='
      },
      controller: function () { 
        this.$onInit = function () {

            let vm = this;

            vm.counter = vm.initialValue;
            vm.increment = increment;
            vm.decrement = decrement;

            function increment() {
                vm.counter += 1;
            }

            function decrement() {
                vm.counter -= 1;
            }
        };
      }
    }
});

>> Demo fiddle

Sign up to request clarification or add additional context in comments.

8 Comments

But I want pass parameters inside the directive and catch them in controller. Is it possible?
@YevhenRadionov no, but you can use E2E binding or parse/access them as scope param or service/factory.
Actually, using the bindToController option on a directive should bind them to the controller instead of the scope. If you add bindToController: true to the directive configuration in the fiddle, you'll see that the $scope passed into the controller no longer has a title attribute and it is instead on the this of the controller. @YevhenRadionov, is that what you want?
@lin so parameters that I pass as a directive attributes I can use only in directive template, right?
@james00794 yes, he is able to achieve this in different ways. I added an example of how to do it with bindToController. Cheers m8
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.