简体   繁体   中英

ng-hide is not getting updated dynamically

I have below div element with nghide

 <div ng-hide="showdiv" class="btnshowall"> 
    <a class="button button-block round outline"
       style="background: transparent !important;" >
      Show All
    </a>
 </div>

and controller as below

.controller('mapCtrl', ['$scope', '$stateParams','User','$cordovaGeolocation','geoFireFac','GoogleMapFac','ConnectivityMonitor','PhysioFac','User',
function ($scope, $stateParams,User,$cordovaGeolocation,geoFireFac,GoogleMapFac,ConnectivityMonitor,PhysioFac,User) {

    console.log('called mapctrl');  
    GoogleMapFac.setUserLoc($scope.map);
    $scope.showdiv = User.getShowDiv();


}])

and User service as

.service('User', ['ToastFac',function(ToastFac){
    return {
         showDiv : false,
        changeShowDiv : function(){
            console.log('in changeShowDiv before change '+this.showDiv);
            this.showDiv = !this.showDiv;
            console.log('in changeShowDiv after change '+this.showDiv);

        },

        getShowDiv : function(){
            return this.showDiv;
        }

I am invoking User.changeShowDiv() from google map's marker click event like below

google.maps.event.addListener(marker, 'click', function () {
      alert('store id '+marker.get('store_id'));
      if(User.showDiv){
          console.log('in if');
          User.changeShowDiv();
          console.log('User.showDiv '+User.showDiv);
      }
      else{
          console.log('in else');
          User.changeShowDiv();
          console.log('User.showDiv '+User.showDiv);
      }

});

logs are coming as expected

in else
services.js:123 in changeShowDiv before change false
services.js:125 in changeShowDiv after change true
services.js:218 User.showDiv true
services.js:211 in if
services.js:123 in changeShowDiv before change true
services.js:125 in changeShowDiv after change false
services.js:213 User.showDiv false
services.js:216 in else
services.js:123 in changeShowDiv before change false
services.js:125 in changeShowDiv after change true
services.js:218 User.showDiv true

By default, as User.showDiv variable is false, showAll button is visible. But button is not hiding & coming by marker click events.

Could someone guide me what I am missing.

Events that come from outside the AngularJS framework need to be brought into the AngularJS framework with $apply :

google.maps.event.addListener(marker, 'click', function () {
      alert('store id '+marker.get('store_id'));
      if(User.showDiv){
          console.log('in if');
          User.changeShowDiv();
          console.log('User.showDiv '+User.showDiv);
      }
      else{
          console.log('in else');
          User.changeShowDiv();
          console.log('User.showDiv '+User.showDiv);
      }
      //IMPORTANT
      $scope.$apply();    
});

AngularJS modifies the normal JavaScript flow by providing its own event processing loop. This splits the JavaScript into classical and AngularJS execution context. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc... You can also use $apply() to enter the AngularJS execution context from JavaScript. Keep in mind that in most places (controllers, services) $apply has already been called for you by the directive which is handling the event. An explicit call to $apply is needed only when implementing custom event callbacks, or when working with third-party library callbacks.

FF

— AngularJS Developer Guide - Integration with the browser event loop


ALSO

Be sure to fix the ng-hide and the controller:

<div ng-hide="showdiv()" class="btnshowall">
$scope.showdiv = function() {
    return User.getShowDiv();
};

In the above code, the ng-hide directive will execute the showdiv() function on each digest cycle and update the visibility of the element accordingly.

You're retrieving value from User.getShowDiv method once only. But when it gets change your are not updating showdiv scope variable. To update value each time you can directly bind the reference of User.getShowDiv method to showdiv scope variable like below

$scope.showdiv = User.getShowDiv; 

There after call showdiv method on HTML, which will eventually evaluate value on each digest cycle unlike other bindings .

ng-hide="showdiv()"

Even above would not solve your problem. Basically you're updating some variable from outside context Angular which is click event. So you have to run digest cycle manually right after updating value from click event listener ran. Just do use $timeout(angular.noop) to fire digest cycle safely.

google.maps.event.addListener(marker, 'click', function () {
      alert('store id '+marker.get('store_id'));
      if(User.showDiv){
          //Code here
      }
      else{
          //Code here
      }
      //manually triggering digest loop to make binding in sync
      $timeout(angular.noop); //It will run new digest cycle.
});

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