当有NG-开关完成渲染?(When has ng-switch finished rendering

2019-10-21 05:02发布

我使用的UI路由器 ,并试图实例化一个小部件,作为一个参数由id指定DOM元素。 此DOM元素是在一个<div ng-switch>和我想打电话当元件被保证存在微件的构造。

<div ng-switch on="state">
  <div ng-switch-when="map">
    <div id="map"></div>
  </div>
</div>

从UI的路由器生命周期 ,我知道我应该挂接到$viewContentLoaded 。 然而,这并不工作-内的DOM元素ng-switch是不是在这一点上创建的:

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()的控制器,它是易碎的50ms的,但那时创建的DOM元素。 可替换地,我可以设置的时间间隔,检查该存在map DOM元素,并且当它的发现清除的时间间隔。

什么是搞清楚时的正确方法是ng-switch已经呈现了DOM? 这是不是证明 。

这里的Plunkr

Answer 1:

我想你在陷阱下降,许多有经验的前端开发人员陷入采用了棱角分明的时候。 在大多数其它JS库,我们修改DOM它已经创建之后,然后将其添加功能。 然而,在角的功能是在HTML定义。 功能和交互是通过使用指令创建。

在jQuery中这样的事情是好的:

<div id="foobar">
    Click here to do stuff
</div>

<script type="text/javascript">
    $(function () {
        $('#foobar').on('click', function () {
            someService.doStuff();
        });
    });
</script>

在角类似下面是更地道:

<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>

但正如你所说,这将重新创建谷歌每一个控制器被击中一次地图。 周围的一种方法是保存这个元素和地图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);
            }

        }
    }
}]);


文章来源: When has ng-switch finished rendering?