【问题标题】:Google Maps API - make callback to directiveGoogle Maps API - 对指令进行回调
【发布时间】:2016-05-02 14:15:22
【问题描述】:

我想使用角度指令嵌入谷歌地图。指令模板运行回调initMap,它应该调用作用域initMap 并创建它,但出现错误:

InvalidValueError: initMap 不是函数

如何从指令的 HTML 模板调用指令回调?

显示地图的父 html 文件:

<my-map></my-map>

指令:

( function( ng, app ) {

    'use strict';

    app.directive( 'myMap', ['$rootScope', function($rootScope) {
        return {
            restrict: 'AE',
            scope : {},
            link: function(scope, element, attr) {
                scope.Template = '/directive_html/map.html';
                scope.initMap = function() {
                     var map = new google.maps.Map(document.getElementById('contact-map'), { ...
                     ...
                };
           },
           template: "<div ng-include='Template'></div>"

Map.html(指令模板html)

<div id='contact-map'></div>

<script src="https://maps.googleapis.com/maps/api/js?callback=initMap" async defer></script>

<script>
    // This is called
    function initMap() {
        // call directive scope.initMap()
    }
</script>

<script src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>

【问题讨论】:

  • 您可以尝试删除script 标签中的async defer 吗?
  • @SabarishSenthilnathan 这并没有解决它
  • 您需要手动初始化地图。加载地图脚本时您的元素将不存在建议使用各种角度地图模块之一以使其更简单
  • 脚本加载器中的回调需要是全局函数,角度范围内的任何东西都不是
  • @charlietfl 请参见上文。我在从回调调用的模板上制作了一个脚本。如何从该函数调用指令 js 中的 scope 函数?

标签: javascript angularjs google-maps


【解决方案1】:

initMap 需要是一个全局函数。

在继续使用可能的解决方案之前,我强烈建议您使用 angular-google-maps 库。

但是,您可以执行以下操作:

  1. initMap 创建为全局函数
  2. 有一个mapLoadedService,一旦 gmap 初始化就会返回一个承诺
  3. resolvemapLoadedServiceinitMap 中的承诺

所以将以下内容添加到您的全局 js 中:

var initMap = function(){    
    var elem = angular.element(document.querySelector('[ng-app]')); //your app qs
    var injector = elem.injector();
    var mapLoadedService = injector.get('mapLoadedService');
    mapLoadedService.loaded();
};

将以下服务添加到您的 Angular 应用中:

app.factory( 'mapLoadedService', ['$q', function($q) {
    var defer = $q.defer();
    this.init = function(){
            return defer.promise;
    };
    this.loaded = function(){
            defer.resolve();
    };
});

然后在你的指令中:

app.directive( 'myMap', ['$rootScope','mapLoadedService', function($rootScope, mapLoadedService) {
    return {
        restrict: 'AE',
        scope : {},
        link: function(scope, element, attr) {
            scope.Template = '/directive_html/map.html';
                //mapLoadedService returns a promise, that only resolves when google maps lib has loaded and is available globally...
                mapLoadedService.init().then(function(){
                    var map = new google.maps.Map(document.getElementById('contact-map'), { });
                });

       },
       template: "<div ng-include='Template'></div>"
    }
});

您还应该在您的index.html 或应用程序库中加载谷歌地图库。

<script src="https://maps.googleapis.com/maps/api/js?callback=initMap" async defer></script>

【讨论】:

    猜你喜欢
    • 2011-02-24
    • 1970-01-01
    • 2011-07-25
    • 1970-01-01
    • 1970-01-01
    • 2011-10-10
    • 2020-05-06
    • 1970-01-01
    相关资源
    最近更新 更多