I'm using ui-router and trying to instantiate a widget that takes as a parameter a DOM element specified by id. This DOM element is in a <div ng-switch>
and I want to call the widget constructor when the element is guaranteed to exist.
<div ng-switch on="state">
<div ng-switch-when="map">
<div id="map"></div>
</div>
</div>
From the ui-router lifecycle, I understand that I should hook into $viewContentLoaded
. This, however, doesn't work - the DOM element within the ng-switch
isn't created at that point:
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('/', {url: '/', templateUrl: 'index.html'})
.state('map', {url: 'map', templateUrl: 'map.html', controller: 'MapCtrl'})
}]);
app.controller('MapCtrl', ['$rootScope', '$scope', '$state', function MapCtrl($rootScope, $scope, $state) {
$scope.state = $state.current.name; // expose the state to the template so we can ng-switch. Apparently there's no better way: https://github.com/angular-ui/ui-router/issues/1482
$scope.$on('$viewContentLoaded', function mapContentLoaded(event, viewConfig) {
var mapElement = document.getElementById('map');
console.log('Attempting to create map into', mapElement);
var map = new google.maps.Map(mapElement); // <-- but mapElement will be null!
});
}]);
What does work is using a setTimeout()
of 50ms in the controller, which is brittle, but by that time the DOM element is created. Alternatively, I can set an interval, check for the presence of the map
DOM element, and clear the interval when it's found.
What is the proper way of figuring out when an ng-switch
has rendered its DOM? This isn't documented.
Here's the Plunkr.