0

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)

Ricky Stam
  • 2,116
  • 21
  • 25

2 Answers2

1

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){})

marcinn
  • 1,786
  • 11
  • 13
0

Avoid using isolated scope directives unless needed. And you know prior to AngularJS 1.2.x isolated scoped and normal directive did not differ much. But with 1.2.x they have changed their behaviour. So, i had to change all the directives in my project. So, make sure, you use then unless needed.

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,
        template: '<a href="#">Hide Amounts</a>',
        link: function (scope, element, attrs) {
            element.click(function () {
                scope.showAmounts = !scope.showAmounts;
                scope.$apply();
            })
        }
    };
}]);

And other thing is you can use the parent scope in the directive (until it is not an isolated scope directive).

Graham
  • 7,431
  • 18
  • 59
  • 84
Vidhya Sagar Reddy
  • 1,521
  • 1
  • 13
  • 25