javascript - ng-switch什么时候完成渲染?

标签 javascript html angularjs angular-ui-router ng-switch

我正在使用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/

相关文章:

javascript - 单击函数之间的 Angular ,共享指令模板

javascript - Angularjs - 网址参数 : When clicked returns to angular vars in the url

javascript - 是否有一种单行代码可以在 Javascript 中使用以参数命名的键创建对象文字?

c# - 根据文本值检查文本框

javascript - onscroll 添加事件类不起作用

jquery - 移动设备上的 Bootstrap 响应问题

javascript - 页脚元素随视口(viewport)均匀扩展

javascript - 函数不会更新变量