Reputation: 2269
Here's a jsFiddle that shows what I'm trying to do: http://jsfiddle.net/P3c7c
I'm using the Google Places AutoComplete widget to obtain lat/long coordinates, which I then wish to use in a subsequent search function. It seemed that the proper way to implement this, considering the need to add an event listener to an element, was to use a directive, and to attach the listener using the directive's linking function. However, inside of this listener, I need it to set the location property of the SearchForm controller, which is its parent. And I have not figured out how to make that connection. Here's the relevant chunk of code:
/* Controllers */
function SearchForm($scope){
$scope.location = ''; // <-- this is the prop I wish to update from within the directive
$scope.doSearch = function(){
if($scope.location === ''){
alert('Directive did not update the location property in parent controller.');
} else {
alert('Yay. Location: ' + $scope.location);
}
};
}
/* Directives */
angular.module('OtdDirectives', []).
directive('googlePlaces', function(){
return {
restrict:'E',
replace:true,
transclude:true,
scope: {location:'=location'}, // <--prob something wrong here? i tried @/& too, no luck
template: '<input id="google_places_ac" name="google_places_ac" type="text" class="input-block-level"/>',
link: function($scope, elm, attrs, ctrl){
var autocomplete = new google.maps.places.Autocomplete($("#google_places_ac")[0], {});
google.maps.event.addListener(autocomplete, 'place_changed', function() {
var place = autocomplete.getPlace();
// THIS IS THE STRING I WANT TO SAVE TO THE PARENT CONTROLLER
var location = place.geometry.location.lat() + ',' + place.geometry.location.lng();
// THIS IS NOT DOING WHAT I EXPECT IT TO DO:
$scope.location = location;
});
}
}
});
Thanks in advance.
Upvotes: 2
Views: 2312
Reputation: 2701
Two minor corrections and it should work:
<google-places location="location"></google-places>
and when you set location inside your directive you also need to do $scope.$apply()
$scope.$apply(function() {
$scope.location = location;
});
You have to do $apply()
because the event happens outside of angular digest loop, so you have to let angular know that something has changed inside the scope and it needs to "digest" it's bi-directional bindings and other internal async stuff.
Also, I don't think you need transclude:true
.
Upvotes: 3