Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why this ng-show ng-hide not working

I have simple app in AngularJS. I want to show messages dynamically when an AJAX request is made. Unfortunately it always in hidden state and I can't figure out why.

HTML:

<div ng-show="message">
    <h2>show</h2>
</div>

<div ng-hide="!message">
    <h2>Hide</h2>
</div>

AngularJS controller:

function merchantListController($scope, $http, $rootScope, $location, global) {
    $http({
        method: 'POST',
        url: global.base_url + '/merchant/list',
    }).success(function($data) {
        if ($data.status === 'success') {
            $scope.merchants = $data.data;

            $scope.$apply(function(){
                $scope.message = true;
            });
        }
    });
}

screenshot

like image 650
Namal Avatar asked Jul 26 '14 08:07

Namal


People also ask

Can we use ng-show and Ng-hide together?

First of all, the two directives can trip over each other( see this JSFiddle, as provided by Joel Skrepnek), and is generally just bad design. You can use a function, another field or just some more inline-logic.

How does ng-hide work?

The ng-hide directive hides the HTML element if the expression evaluates to true. ng-hide is also a predefined CSS class in AngularJS, and sets the element's display to none .

What is Ng-show and Ng-hide?

The ng-show directive shows or hides the given HTML element based on the expression provided to the ng-show attribute. The ng-hide directive shows or hides the given HTML element based on the expression provided to the ng-hide attribute .


1 Answers

The likely reason it is not working is because you are creating a new scope property within a child scope, instead of overwriting the message property in merchantListController's scope as you would have expected.

// The following assignment will create a 'message' variable 
// in the child scope which is a copy of the scope variable   
// in parent scope - effectively breaking two-way model binding.
$scope.message = true;

To resolve this, make sure that you bind by reference to a property on your model rather than to a property on scope.

HTML

<div ng-show="my.message">
   <h2>show</h2>
</div>

<div ng-hide="!my.message">
   <h2>Hide</h2>
</div>

Controller

function merchantListController($scope, $http, $rootScope, $location, global) {

   // Initialize my model - this is important!
   $scope.my = { message: false };

   $http({
        method: 'POST',
        url: global.base_url + '/merchant/list',
    }).success(function($data) {

        if ($data.status === 'success') {
            $scope.merchants = $data.data;

            // modify the 'message' property on the model
            $scope.my.message   = true;
        }

    });
});

Explanation

The reason this works is because the model my is being resolved using scope inheritance rules. That is, if my does not exist in current scope, then search for my in the parent scope, until it is either found, or the search stops at $rootScope. Once the model is found, the message property is overwritten.

like image 72
pixelbits Avatar answered Oct 13 '22 06:10

pixelbits