简体   繁体   中英

AngularJS cannot access directive scope inside controller

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>

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM