Моя директива использует сервис, который возвращает обещание, мне нужно отобразить атрибуты области geoZip, geoCity и geoState в шаблоне.
Проблема в том, что эти переменные области не отображаются в шаблоне, я просто вижу запятую.
Что делать, чтобы отображать переменные области?
Это мой код директивы:
.directive('cityStateZip', function() {
return {
restrict: 'A',
transclude: true,
scope: {
zip: '=',
},
template: '<p>{{geoCity}}, {{geoState}} {{geoZip}}</p>',
controller: ['$scope', 'GeolocationService', function ($scope, GeolocationService) {
GeolocationService.geocode($scope.zip).then(function(result) {
if (result) {
console.log(result);
$scope.geoZip = result['address_components'][0]['long_name'];
$scope.geoCity = result['address_components'][1]['long_name'];
$scope.geoState = result['address_components'][2]['short_name'];
}
});
}]
};
})
.service('GeolocationService', ['underscore', '$q', function (underscore, $q) {
var gs = {};
gs.geocode = function(address) {
var geocoder = new google.maps.Geocoder();
var deferred = $q.defer();
geocoder.geocode( { "address": address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK && results.length > 0) {
return deferred.resolve(underscore.first(results));
}
return deferred.reject();
});
return deferred.promise;
}
return gs;
}]);
Я обнаружил, что мне нужно использовать услугу $ timeout, чтобы заставить ее работать:
.directive('cityStateZip', function() {
return {
restrict: 'A',
transclude: true,
scope: {
zip: '=',
},
template: '<p>{{geoCity}}, {{geoState}} {{geoZip}}</p>',
controller: ['$scope', '$timeout', 'GeolocationService', function ($scope, $timeout, GeolocationService) {
GeolocationService.geocode($scope.zip).then(function(result) {
if (result) {
console.log(result);
$timeout(function() {
$scope.geoZip = result['address_components'][0]['long_name'];
$scope.geoCity = result['address_components'][1]['long_name'];
$scope.geoState = result['address_components'][2]['short_name'];
});
}
});
}]
};
})
Пожалуйста, дайте мне знать, если есть лучшая альтернатива (не используя $ timeout), спасибо!
$timeout
рекомендуется авторами AngularJS как лучший способ сделать «безопасное применение $». GeolocationService является асинхронным циклу дайджеста AngularJS. $timeout
дает браузеру возможность наверстать упущенное и синхронизироваться с циклом дайджеста.
geocode()
. Судя по именам свойств, похоже, что вы используете google ... который находится вне углового контекста, и вам нужно будет где-то $ apply, чтобы сообщить angular для запуска дайджеста