【问题标题】:How to bind google maps using HotTowel?如何使用 HotTowel 绑定谷歌地图?
【发布时间】:2013-07-27 13:46:09
【问题描述】:

我正在尝试在 HotTowel 中显示一个简单的地图。

在 home.html 页面我有:

<section>
  <div id="map-canvas" data-bind="map: map"></div>
</section>

在 home.js 我有那个:

define(['services/logger'], function (logger) {
  var vm = {
    activate: activate,
    title: 'Home View',
    map: map
};

  return vm;

  function activate() {
    google.maps.event.addDomListener(window, 'load', initialize);
    logger.log('Home View Activated', null, 'home', true);
    return true;
  }

  var map;
  function initialize() {
    var mapOptions = {
      zoom: 8,
      center: new google.maps.LatLng(-34.397, 150.644),
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
  }
});

如何将模型与视图绑定以显示地图?

【问题讨论】:

    标签: javascript durandal hottowel


    【解决方案1】:

    编辑**

    以下答案适用于 Durandal 1.2。在 durandal 2.0 中,viewAttached 事件被重命名attached。你可以阅读有关它的 Durandals 文档here


    Durandal 有一个 viewAttached 事件,一旦视图被数据绑定并附加到 dom,就会在您的视图模型上调用该事件。那将是调用 google maps api 的好地方。

    define(['services/logger'], function (logger) {
      var vm = {
        viewAttached: initialize
        title: 'Home View',
        map: map
    };
    
      return vm;
    
      var map;
      function initialize(view) {
        logger.log('Home View Activated', null, 'home', true);
        var mapOptions = {
          zoom: 8,
          center: new google.maps.LatLng(-34.397, 150.644),
          mapTypeId: google.maps.MapTypeId.ROADMAP
        };
    
        map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
      }
    });
    

    再次编辑以解决人们的问题**

    根据 Jamie Hammond 的评论,将 DOM 横向范围限定为附加的视图是一种更好的做法。如果 DOM 元素是视图的一部分。

    因此,在您的 viewAttached(在 durandal 1.2 中)或 attached(在 durandal 2.0 中)内,您将:

    var map;
    var mapOptions = { /*map options*/ };
    var vm = {
       attached: function (view) {
           var mapCanvas = $('#map-canvas', view).get(0);
           map = new google.maps.Map(mapCanvas, mapOptions);
       }
    }
    

    我根本没有搞砸 Durandal 2.0,因为我一直忙于工作和其他事情,当我搞砸 Durandal 1.0 时,这只是为了好玩,但我确实喜欢这个框架,并希望有一天能得到玩2.0。话虽如此,我确实在 Durandal 1.0 的附加视图中生成地图时遇到了问题。但是,我没有使用谷歌地图。我正在使用 Leafletjs。我对该问题的解决方案是在 viewAttached 中创建一个延迟,该延迟会在短暂延迟后重新绘制地图。这是因为 Durandal 在视图中的转换不能很好地与传单在 dom 元素中绘制地图的能力配合使用,因为它正在飞行和淡入。

    所以,在 viewAttached 中,我会像这样绘制地图:

    window.setTimeout(drawMap, 10);
    

    同样,这是我遇到的一个非常具体的问题,而不是 Durandal 的问题。当 DOM 元素仍在过渡时,Leafletjs 无法正确渲染地图,这更是一个问题。

    【讨论】:

    • 在 Durandal 2.0 中,“viewAttached”被重命名为“attached”。此外,即使您修复了明显的语法错误(例如在初始化后添加逗号),上面的代码也无法正常工作。和其他人一样,我仍在寻找一种适用于新 google API 的解决方案。
    • 您应该始终将范围限定为视图。例如 $(view).find('#map-canvas')
    • 您是否正在向 google 加载类似 Google Maps Web Services API wrapper for .NET 0.30.0 nuget.org/packages/GoogleMapsApi 或者您如何开始使用谷歌地图?
    • 我认为 nuget 包是用于 .net 库的。我指的是 google maps javascript 库。
    【解决方案2】:

    首先转到您的 main.js 并添加 'async': '../Scripts/async',

    require.config({
        paths: {
            'text': '../Scripts/text',
            'durandal': '../Scripts/durandal',
            'plugins': '../Scripts/durandal/plugins',
            'mapping': '../Scripts/knockout.mapping-latest',
            'async': '../Scripts/async',
            'transitions': '../Scripts/durandal/transitions'
        },
        shim: { mapping: { deps: ['knockout'] } }
    });
    

    请注意,我们需要在脚本文件夹中添加 async.js,因此请转到 Download async.js 下载文件并将其作为 async.js

    保存在 hottowel 脚本文件夹中

    ma​​in.js中添加这个

    // convert Google Maps into an AMD module
    define('gmaps', ['async!http://maps.google.com/maps/api/js?v=3&sensor=false'],
    function(){
        // return the gmaps namespace for brevity
        return window.google.maps;
    });
    

    在任何视图模型中,您现在都可以像这样使用它

    define(['plugins/router', 'knockout', 'services/logger', 'durandal/app', 'gmaps'], function (router, ko, logger, app, gmaps) {
    

    我希望这会有所帮助:

    【讨论】:

      【解决方案3】:

      布雷特,

      对我来说,问题是高度是 0px。我的工作模块如下所示:

      define(['plugins/router', 'knockout', 'plugins/utility'], function (router, ko, utility) { 变种 vm = { }; vm.map = 未定义;

      vm.compositionComplete = function () {
      
          var myLatlng = new google.maps.LatLng(29.4000, 69.1833);
          var mapOptions = {
              zoom: 6,
              center: myLatlng
          }
      
          vm.map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
      
          var georssLayer = new google.maps.KmlLayer({
              url: 'http://www.visualtravelguide.com/Pakistan-Islamabad.kmz'
          });
          georssLayer.setMap(vm.map);
      
          utility.resizeElementHeight(document.getElementById('map-canvas'), 10);
          $(window).resize(function () {
              utility.resizeElementHeight(document.getElementById('map-canvas'), 10);
          });
      
      };
      
      return vm;
      

      });

      我的实用程序模块如下所示:

      define(['jquery','knockout'], function ($,ko) {

      return {
      
          //resizes an element so height goes to bottom of screen, got this from a stack overflow
          //usage:
          // resizeElementHeight(document.getElementById('projectSelectDiv'));
          //$(window).resize(function () {
          //     resizeElementHeight(document.getElementById('projectSelectDiv'));
          //});
          //adjustpixels is an optional parameter if you want to leave room at the bottom
          resizeElementHeight: function (element,adjustPixels) {
              var height = 0;
              var adjust = 0;
              if (adjustPixels != undefined)
                  adjust = adjustPixels;
              var body = window.document.body;
              if (window.innerHeight) {
                  height = window.innerHeight;
              } else if (body.parentElement.clientHeight) {
                  height = body.parentElement.clientHeight;
              } else if (body && body.clientHeight) {
                  height = body.clientHeight;
              }
              element.style.height = ((height - element.offsetTop-adjust) + "px");
          },
          //looks up name by id, returns blank string if not found
          //pass in a list and an id (they can be observables)
          LookupNameById: function (l, wId) {
                  var list = ko.utils.unwrapObservable(l);
                  var id = ko.utils.unwrapObservable(wId);
                  var name = '';
                  $.each(list, function (key, value) {
      
                      if (value.Id() == id)
                          name = value.Name();
                  });
      
                  return name;
          },
          //sets the widths of the columns of headertable to those of basetable
          setHeaderTableWidth: function (headertableid,basetableid) {
              $("#"+headertableid).width($("#"+basetableid).width());
              $("#"+headertableid+" tr th").each(function (i) {
                  $(this).width($($("#"+basetableid+" tr:first td")[i]).width());
              });
              $("#" + headertableid + " tr td").each(function (i) {
                  $(this).width($($("#" + basetableid + " tr:first td")[i]).width());
              });
          }
      
      };
      

      });

      希望对你有所帮助。

      【讨论】:

        【解决方案4】:

        埃文,

        我也试图让这个工作,但没有快乐。 我的 html 和 viewmodel 和你的完全一样,我知道 viewAttached 组合被调用了,因为我得到了我的记录器事件 - 但没有地图!

        我能想到的唯一其他事情是您从哪里调用您的 googlemaps?我在我的 index.html 中做的你也在做同样的事情吗?

        问候

        【讨论】:

        • 你能添加 logger.log(document.getElementById('map-canvas')) 看看你是否能够从那个 viewattached 事件中获得对 dom 元素的引用
        • 对我来说,一切运行都没有错误,并将东西放入地图画布 div,但之后什么也没有发生。我不明白为什么使用附加而不是组合完成?在其他包含之前或之后包含 google API 脚本文件是否重要?
        • 查看我刚刚发布的答案,它可能对您有用
        • 浏览器将按照您引用它们的顺序异步下载脚本,一旦下载,它将以相同的顺序执行它们。因此,取决于您何时调用 google maps api。我会确保在此之前加载 google 脚本。
        • 感谢您 - 在浏览器开发工具中检查解析的 html 后,我意识到它也将我的包含 div 设置为 0px 的高度!呸,这让我发疯了!
        猜你喜欢
        • 2011-09-12
        • 2017-05-06
        • 2017-11-01
        • 2020-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多