我正在使用ui-router并尝试实例化一个小部件,该小部件将 id 指定的 DOM 元素作为参数。此 DOM 元素位于 <div ng-switch>
中我想在保证元素存在时调用小部件构造函数。
<div ng-switch on="state">
<div ng-switch-when="map">
<div id="map"></div>
</div>
</div>
来自ui-router lifecycle ,我明白我应该挂入 $viewContentLoaded
。然而,这不起作用 - ng-switch
中的 DOM 元素此时尚未创建:
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!
});
}]);
有效的是使用 setTimeout()
Controller 中的时间为 50 毫秒,这很脆弱,但那时 DOM 元素已创建。或者,我可以设置一个时间间隔,检查 map
是否存在。 DOM元素,找到后清除间隔。
确定 ng-switch
何时出现的正确方法是什么?已经渲染了它的 DOM?这个isn't documented .
这是 Plunkr 。
最佳答案
我认为您正在陷入许多经验丰富的前端开发人员在使用 Angular 时陷入的陷阱。在大多数其他 JS 库中,我们在创建 DOM 后对其进行修改,然后向其添加功能。然而,在 Angular 中,功能是在 HTML 中定义的。功能和交互性是通过使用指令创建的。
在 jQuery 中这样的东西很好:
<div id="foobar">
Click here to do stuff
</div>
<script type="text/javascript">
$(function () {
$('#foobar').on('click', function () {
someService.doStuff();
});
});
</script>
而在 Angular 中,类似下面的内容更为惯用:
<div id="foobar" ng-controller="Main" ng-click="doStuff()">
Click here to do stuff
</div>
<script type="text/javascript">
app.controller('Main', ['$scope', 'somerService', function ($scope, someService) {
$scope.doStuff = function () {
someService.doStuff();
}
}]);
</script>
对于 GoogleMap 指令,这是迄今为止实现它的最简单方法。尽管这是非常基本的,并且可能无法完成您需要的所有操作。
app.directive('googleMap', [function() {
return {
link: function(element) {
new google.maps.Map(element);
}
}
}
]);
您的map.html
:
<div ng-switch on="state">
<div ng-switch-when="map">
<div google-map id="map"></div>
</div>
</div>
正如您所提到的,每次点击该 Controller 时,这都会重新创建 Google map 。解决这个问题的一种方法是保存元素和 Map api 并在后续调用中替换它:
app.directive('googleMap', [function () {
var googleMapElement,
googleMapAPI;
return {
link: function (element) {
if (!googleMapElement || !googleMapAPI) {
googleMapAPI = new google.maps.Map(element);
googleMapElement = element;
}
else {
element.replaceWith(googleMapElement);
}
}
}
}]);
关于javascript - ng-switch什么时候完成渲染?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26579678/