【问题标题】:Meteor infinite loop with Session variables带有会话变量的流星无限循环
【发布时间】:2016-05-16 06:36:14
【问题描述】:

我是 Meteor 的新手,遇到了一个问题,不知道如何解决。

我想将日期存储在集合中。我可以使用谷歌地图来获取会议地点,这给了我一个带有坐标的字符串。 我使用 jaymc:google-reverse-geocode 对坐标进行反向地理编码,这基本上是有效的(我可以 console.log 结果)。

当使用会话变量时,我可以输出结果,但它们会不断改变自己。条目到达那里的结果,然后第一个和第二个条目改变它们的结果,然后它们再次改变等等。

我尝试使用 ReactiveVar 和 ReactiveDict 但没有结果。我无法从 reverseGeocode 函数返回任何结果。

代码如下:

{{#each termine}}
   <div class="listTermine">
   <p class="title">{{title}}</p>
   <p class="desc">{{desc}}</p>
   <p class="location">{{getAddress}}</p>
   <p class="dates">
   <span class="glyphicon glyphicon-time" aria-hidden="true"></span>
  {{formatDate startDate}} bis {{formatDate endDate}}
  </p>
</div>
{{/each}}


Template.showTermine.helpers({
    getAddress: function() {
        var locArray = Termine.findOne({
            "title": this.title
        }, {
            fields: {
                locations: 1
            }
        });
        latlngArray = locArray.locations.toString();
        var latlong = latlngArray.split(",");
        var lat = latlong[0];
        var lng = latlong[1];
        reverseGeocode.getLocation(lat, lng, function(location) {
                Session.set('location', reverseGeocode.getAddrStr());
            })
            // commented out to prevent infinite loop
            //return Session.get('location');
    }
});

【问题讨论】:

    标签: session meteor reverse geocode


    【解决方案1】:

    这是因为 Reactive 变量(如 Session 变量)会导致它所包含的整个函数在每次更改时重新运行。 p>

    所以这里你有 Session.set()Session.get() 相同的函数,所以它会在每次调用 Session.set() 时重新运行 getAddress 函数,这将在循环中重新运行事物.

    由于您在同一个函数中返回结果,因此您实际上根本不需要 Session 变量:

    你可以简单地:

    reverseGeocode.getLocation(lat, lng, function(location) {
                    return reverseGeocode.getAddrStr();
                })
    

    如果这不起作用(因为您正在对 .getLocation 进行异步调用),那么您应该在其他地方进行此调用

    最好的方法是在Template.mytemplate.onCreated() 事件中

    Template.showTermine.onCreated(function() {
            var locArray = Termine.findOne({
                "title": this.title
            }, {
                fields: {
                    locations: 1
                }
            });
            latlngArray = locArray.locations.toString();
            var latlong = latlngArray.split(",");
            var lat = latlong[0];
            var lng = latlong[1];
            reverseGeocode.getLocation(lat, lng, function(location) {
                    Session.set('location', reverseGeocode.getAddrStr());
            })});
    
    Template.showTermine.helpers({
      "getAddress": function() {
         return Session.get("location");
      }
    });
    

    【讨论】:

    • 感谢您的回答!一切都有意义,除了 mongo 查询。 Theres this.title 包括在内,这就像它应该在辅助函数中一样工作。获取数据的最佳实践是什么?我试图在辅助函数中获取日期并将其传递给 onCreated 函数,但这似乎不起作用。
    【解决方案2】:

    set 在回调中调用,回调将在助手返回 get 后执行,这意味着当它设置变量时,助手会因为会话值的变化而失效并重新运行。

    几个可能的修复: 移动代码以将 var 设置到 onCreated 或 onRendered 方法中,并删除从帮助程序返回的所有内容

    或者 确保会话 var 最初创建为空值,然后在尝试调用位置服务或设置 var 之前添加一个 if 检查以查看 var 的值。

    Reactive vars 是在这里为重复模板检查会话的正确方法,以避免会话中的命名空间冲突,并且相同的建议应该适用于响应式 vars 或会话 vars。只需避免在同一个助手中设置和获取任何反应性内容,而无需进行一些检查以查看是否需要它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-07
      • 2016-08-24
      • 1970-01-01
      • 1970-01-01
      • 2016-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多