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

查看:183
本文介绍了当有NG-开关完成渲染?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

href=\"https://github.com/angular-ui/ui-router\" rel=\"nofollow\"> UI路由器,并试图实例化一个小部件,如需要参数由id指定DOM元素。这DOM元素是在< D​​IV NG开关方式> ,我想打电话时,该元素是保证存在窗口部件的构造

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>

从<一个href=\"http://stackoverflow.com/questions/20745761/what-is-the-angular-ui-router-lifecycle-for-debugging-silent-errors\">ui-router生命周期,我知道我应该钩到 $ viewContentLoaded 。然而,这并不奏效 - 在中的DOM元素NG-开关在这一点上没有创建:

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!
  });
}]);

这是什么工作是使用的setTimeout()的控制器,这是脆的,但那时创建的DOM元素50ms的。或者,我可以设置的时间间隔,检查地图 DOM元素的presence,当它的发现清除的时间间隔。

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.

什么是的正确的搞清楚当 NG-开关已呈现了DOM的方法是什么?这未记录

What is the proper way of figuring out when an ng-switch has rendered its DOM? This isn't documented.

这里的 Plunkr

Here's the Plunkr.

推荐答案

我觉得你在陷阱下降,许多有经验的前端开发人员在使用落角时。在大多数其他JS库,我们修改DOM,它已经创建之后,然后将其添加功能。但是,在角度的功能是在HTML所定义。功能和交互性是通过使用指令创建的。

I think you're falling in the trap that many experienced front-end developers fall in to when using Angular. In most of other JS libraries we modify the DOM after it's been created and then add functionality to it. However, in Angular the functionality is defined in the HTML. Functionality and interactivity is created by using directives.

在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的指令,这是迄今为止完成它的最简单方法。虽然这是令人难以置信的基础,不能做一切你需要它。

As for your GoogleMap directive this is by far the simplest way to accomplish it. Albeit this is incredibly basic and may not do everything you need it to.

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并替换它在后续调用

As you mentioned however, this would recreate the Google map every time that controller is hit. One way around that is to save off the element and Map api and replacing it on subsequent calls:

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);
            }

        }
    }
}]);

这篇关于当有NG-开关完成渲染?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆