vcliment89
vcliment89

Reputation: 75

Directive two way binding

I'm relative new to AngularJS and trying to create a directive for add some buttons. I'm trying to modify the controller scope from inside the directive but I can't get it to work. Here is an example of my app

app.controller('invoiceManagementController', ['$scope', function ($scope) {
    $scope.gridViewOptions = {
        isFilterShown: false,
        isCompact: false
    };
}]);

app.directive('buttons', function () {
    return {
        restrict: 'A',
        template: '<button type="button" data-button="search" title="Filter"><i class="glyphicon glyphicon-search"></i></button>',
        scope: {
            gridViewOptions: '='
        },
        transclude: true,
        link: function (scope, element, attr, ctrl, transclude) {
            element.find("button[data-button='search']").bind('click', function (evt) {
                // Set the property to the opposite value
                scope.gridViewOptions.isFilterShown = !scope.gridViewOptions.isFilterShown

                transclude(scope.$parent, function (clone, scope) {
                    element.append(clone);
                });
            });
        }
    };
});

My HTML like following

{{ gridViewOptions.isFilterShown }}
<div data-buttons="buttons" data-grid-view-options="gridViewOptions"></div>

The scope inside the directive does change but is like isolated, I did try paying with the scope property and transclude but I'm probably missing something, would appreciate some light here

Upvotes: 0

Views: 181

Answers (2)

vcliment89
vcliment89

Reputation: 75

Ok finally found a solution for this after some more research today. Not sure if the best solution, but this works so good for now.

app.controller('invoiceManagementController', ['$scope', function ($scope) {
    $scope.gridViewOptions = {
        isFilterShown: false,
        isCompact: false
    };
}]);

app.directive('buttons', function () {
    return {
        restrict: 'A',
        template: '<button type="button" data-button="search" data-ng-class="gridViewOptions.isFilterShown ? \'active\' : ''" title="Filter"><i class="glyphicon glyphicon-search"></i></button>',
        scope: {
            gridViewOptions: '='
        },
        link: function (scope, element, attr, ctrl, transclude) {
            element.find("button[data-button='search']").bind('click', function (evt) {
                scope.$apply(function () {
                    // Set the property to the opposite value
                    scope.gridViewOptions.isFilterShown = !scope.gridViewOptions.isFilterShown;
                });
            });
        }
    };
});

Upvotes: 0

Michael Kang
Michael Kang

Reputation: 52867

When you modify scope inside of your directive's link function, you are modifying your directive's isolated scope (because that is what you have set up). To modify the parent scope, you can put the scope assignment inside of your transclude function:

transclude(scope.$parent, function (clone, scope) {
    // Set the property to the opposite value
    scope.gridViewOptions.isFilterShown = !scope.gridViewOptions.isFilterShown
    element.append(clone);
});

Upvotes: 0

Related Questions