3

我有以下模板:

<template name="test">
  {{#isolate}}
    <div id="map_canvas" style="width:50%; height:50%"></div>
  {{/isolate}}
</template>

在我的 test.js 中(来自https://developers.google.com/maps/documentation/javascript/tutorial#HelloWorld):

function initialize(){
  var mapOptions = {
    center: new google.maps.LatLng(-34.397, 150.644),
    zoom: 8,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  var map = new google.maps.Map($("#map_canvas")[0], mapOptions);
}

Template.test.rendered = function(){
    initialize();
  //*** The following is the workaround I am using:***
  // if (! this.initialized){
  //   initialize();
  //   this.initialized = true;
  // }
};

问题是:如果没有注释代码部分中显示的解决方法,模板总是被渲染两次(因为 initialize() 运行)。它既显示在控制台日志中(此处未显示日志记录代码),也可以从闪烁一次的地图中看到(这是不可接受的)。

原因,我猜,是从以下事件发生:

  1. 模板被渲染,$('#map_canvas')生成为一个简单的 div 元素(没有附加地图);
  2. google map api 返回 aync-ly 并修改$('#map_canvas')
  3. Meteor 以某种方式检测到更改,尽管如此{{#isolate}},仍决定再次渲染整个模板(这显示在日志中);
  4. 在 .initialize() 内再次调用Template.test.rendered

我的问题:

  1. 为什么?
  2. 如果发生了这种情况,为什么 Meteor 只渲染两次,而不是无限次?
  3. 解决方案?

3个问题,非常感谢!

4

1 回答 1

4

由于包含{{> test}}被重新渲染的外部上下文,模板可能被渲染了两次。发生这种情况的原因有很多,但通常只是它最初呈现时没有订阅数据,然后在数据加载后第二次呈现。

无论如何,在你的具体情况下,我认为你想要的是{{#constant}}你的谷歌地图的包装,而不是{{#isolate}}.

注意:如果(无论出于何种原因)周围的上下文被重新渲染,{{#constant}}区域被重新渲染。然而,新版本被丢弃而不是在 DOM 中被替换。所以在你回调时要小心,只在第一次rendered做某事。

于 2012-11-12T05:51:25.420 回答