简体   繁体   中英

Two way data binding with directive doesn't work

I have a controller used to add tasks. On that page a user needs to select a group to act upon. I have written a directive that is used to allow a user to pick groups (folders)

My page controller

function AddTaskController($scope) {
    var vm = this;

    vm.group = { whatsit: true };

    $scope.$watch("vm.group", function () {
        console.log("controller watch", vm.group);
    },true);
}

The page html where the directive is used

<em-group-selection group="vm.group"></em-group-selection>

The directive configuration

function GroupSelectionDirective() {
    return {
        scope: {
            group: '='
        },
        controller: GroupSelectionDirectiveController,
        controllerAs: 'vm',
        templateUrl: '/views/templates/common/folderselection.html'
    };
}

The directive controller:

function GroupSelectionDirectiveController($scope) {
    var vm = this;

    $scope.$watch("group", function () { console.log("yo1", vm.group); }, true)
    $scope.$watch("vm.group", function () { console.log("yo2", vm.group); }, true)
}

Now when this fires, both console.log() calls in the directive fire once, with undefined . They never fire again. If in the controller I set vm.group to something else the $watch in the AddTaskController never gets fired.

Why isnt the data binding working?


Update:

I notice that if, in the directive, I change the init() function in my directive to use $scope it works! Can I not, as Fedaykin suggests, use controllerAs with two way data binding?

function init() {
    $timeout(function () {
        $scope.group.shizzy = 'timeout hit';
    }, 200);
}

Turns out that if you use isolate scopes and controlelrAs syntax you need to also use bindToController : true . Without this you will not be able to only use vm and will have to use $scope for the isolate scope variables

More information can be found in the John Papa style guide and this SO answer

The final directive setup is as so:

function GroupSelectionDirective() {
    return {
        scope: {
            group: '='
        },
        controller: GroupSelectionDirectiveController,
        controllerAs: 'vm',
        bindToController: true,
        templateUrl: '/views/templates/common/folderselection.html'
    };
}

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