Reputation: 40159
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.
Upvotes: 0
Views: 55
Reputation: 48968
Events created by third-party applications need to be brought into the AngularJS framework using $scope.$apply
:
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', function(e) {
$scope.$apply(function() {
$scope.MarkerClicked(e)
});
});
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.
— AngularJS Developer Guide - Integration with the browser event loop
Upvotes: 1
Reputation: 924
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>
Upvotes: 1