angularjsangularjs-ng-show

Scope function executes but the HTML never changes


Scope of an AngularJS scope variable

I have this in my HTML

{{searchDialog.visible}}

and this in my controller

$scope.searchDialog = {'visible' : false};   // initialize

$scope.MarkerClicked = function(e)
{
    $scope.searchDialog.visible = true;
}

These are the only mentions of $scope.searchDialog. I beakpoint the $scope.MarkerClicked function and watch the value toggle to true, but the HTML never changes.

What am I doing wrongly? Is there a scope problem (no pun intended)?

Aha!! $scope.MarkerClicked is a callback from clicking a Leaflet map marker

var marker = L.marker(pubLatLng,
    {
        draggable: false,
        title: title,
        icon: new L.DivIcon({
            html: '<img class="my-div-image" src="js/3rd_party/leaflet/images/'
                       + iconImage + '" />'
                + '<span style="color:red">' + companyName + '</span>',
        })
    }).addTo($scope.map).on('click', $scope.MarkerClicked);

Is that somehow causing my problem? I can't see how, as the marker is added in a $scope function and the callback also handled in a $scope function.


Solution

  • This problem is related to Angular Digest Cycle, as MarkerClicked method was called, but it was outside the scope of Angular Digest Cycle, so You have to explicitly called digest cycle.

    And to solve this issue please take a look at below code snippet, where if we don't add $scope.$apply(), $scope.message will not get updated, and after adding $scope.$apply() in below example which automatically triggers $rootScope.$digest(). As a result, the watchers are fired as usual and the view updates.

    /* What happens with $apply */ 
    angular.module('myApp',[]).controller('MessageController', function($scope) {
        
          $scope.getMessage = function() {
            setTimeout(function() {
              $scope.$apply(function() {
                //wrapped this within $apply
                $scope.message = 'Fetched after 3 seconds'; 
                console.log('message:' + $scope.message);
              });
            }, 2000);
          }
          
          $scope.getMessage();
        
        });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular.min.js"></script>
    
    <body ng-app="myApp">
      <div ng-controller="MessageController">
        Delayed Message: {{message}}
      </div>  
    </body>