javascriptangularjsrootscope

Angular Directive that Toggles Visibility of Elements


I've build a directive that change the $rootScope.showContent value to true or false.

Then i use ng-show="showContent" in order to Hide or Show elements.

This approach works fine but i want to avoid using $rootScope and also the use of scope.apply() function. Can you suggest me a better way to do it?

Below you'll find some code :

HTML

<body ng-app="myApp">
    <div ng-controller="AppCtr">
        <hide-amounts ></hide-amounts>

        <div ng-show="showContent">
            <h1>Hello from h1</h1>
            <p>Hello from paragarapsh</p>
        </div>
         <div ng-show="showContent">
            <h1>Hello from h1</h1>
            <p>Hello from paragarapsh</p>
        </div>
    </div>
</body>

Angular

var myApp = angular.module('myApp', []);

myApp.run(function ($rootScope) {
    $rootScope.showContent = true;
})

myApp.controller("AppCtr", function ($scope) {

})
.directive('hideAmounts',["$rootScope", function ($rootScope) {
    return {
        restrict: "E",
        replace: true,
        template: '<a href="#">Hide Content</a>',
        link: function (scope, element, attrs) {
            element.click(function () {
                scope.$apply(function () {
                    $rootScope.showContent = !$rootScope.showContent;
                })
                return false;
            })
        }
    };
}]);

Jsfiddle link : http://jsfiddle.net/RickyStam/AkVzz/ (jsfiddle not working don't know why :P)


Solution

  • To be honest its not good idea to define directive just to toggle flag on parent controller

    just use

    <button ng-click="showContent = !showContent ">
    

    instead.

    However if you would really like to get rid og $rootScope you can:

    1) Pass parameter to directive jsfiddle

     <hide-amounts show="showAmounts" ></hide-amounts>
    
    var myApp = angular.module('myApp', []);
    
    myApp.controller("AppCtr", function ($scope) {
        $scope.obj = {};
        $scope.obj.showAmounts = true;
        $scope.showAmounts = true;
    })
    .directive('hideAmounts',["$rootScope", function ($rootScope) {
        return {
            restrict: "E",
            replace: true,
            scope: {show:'='},
            template: '<a href="#">Hide Amounts</a>',
            link: function (scope, element, attrs) {
                element.click(function () {
                    scope.$apply(function () {
                        scope.show = !scope.show;
                    })
                    return false;
                })
            }
        };
    }]);
    

    2) send message to parent controller by invoking $scope.emit('message', param) in the directive and registering listener on parent controller $scope.on('message, function(s, param){})