Session 对会话更改的订阅会导致#每个重新绘制每个实体

Session 对会话更改的订阅会导致#每个重新绘制每个实体,session,meteor,reactive-programming,Session,Meteor,Reactive Programming,这里有一个问题:我使用存储用户的坐标。以下是我的实现: updateLoc = function () { var position = Geolocation.latLng() || {lat:0,lng:0}; Session.set('lat', position.lat); Session.set('lon', position.lng); }; Meteor.startup(function() { updateLoc(); // set at 0,

这里有一个问题:我使用存储用户的坐标。以下是我的实现:

updateLoc = function () {
    var position = Geolocation.latLng() || {lat:0,lng:0};
    Session.set('lat', position.lat);
    Session.set('lon', position.lng);
};

Meteor.startup(function() {
    updateLoc(); // set at 0, 0 to begin with
    Meteor.setTimeout(updateLoc, 1000); // get first coordinates 1 second in
    Meteor.setInterval(updateLoc, 5000); // then, every 5 seconds
});
根据这两个会话变量,我有一个
entitiesList
路由等待订阅实体:

this.route('entitiesList', {
    path: '/',
    waitOn: function() {
        if (Meteor.userId())
            return Meteor.subscribe('entities', {lat: Session.get('lat'),lon: Session.get('lon')});
    },
    data: function() {
        return {entities: Entities.find()};
    }
});
以下为刊物:

Meteor.publish('entities', function (position) {
    if (position.lon !== null && position.lat !== null) {
        return Entities.find({location: {
            $near: {$geometry:{type: "Point", coordinates: [position.lon, position.lat]},$maxDistance:500}}
        }});
    }
    this.ready();
});
最后,entitiesList模板:

<template name="entitiesList">
  <div class="entities">
    <h1>Entities list</h1>
    {{#each entities}}
      {{> entityItem}}
    {{else}}
        <p>No entity found. Looking up...</p>
        {{>spinner}}
    {{/each}}
  </div>
</template>

实体列表
{{{#每个实体}}
{{>entityItem}
{{else}
未找到实体。抬头看

{{>微调器} {{/每个}}
现在!这个解决方案有效。实体正确列出,并根据用户位置每5秒更新一次

唯一的问题在于呈现:当反应性是由于会话变量的更新引起的时,整个实体集将被删除并重新绘制。但是,当实体集合中发生更改(例如,删除/创建实体)时,模板中只会相应地重新呈现此更改


这会产生一个列表,每5秒就会令人恼火地闪烁一次。我想删除
#每个
块,然后在模板的
呈现的
函数中使用
this.autorun()
自己编写,并使用jQuery以更优化的方式重新绘制列表,但这将是一种令人讨厌的黑客行为,在模板文件之外有HTML代码块。。。肯定还有别的办法

每次更改会话变量时,您的订阅都会加载,Iron Router会设置其加载模板,这就是为什么它会闪烁

您可以执行以下操作,而不是使用熨斗路由器:

Template.entitiesList.created=function()
{
    var self=this
    this.isLoading=new ReactiveVar(false)
    this.isFirstLoading=new ReactiveVar(true)
    this.autorun(function(){

        self.isLoading.set(true)
        Meteor.subscribe('entities', {lat: Session.get('lat'),lon: Session.get('lon')},function(err){
            self.isLoading.set(false)
            self.isFirstLoading.set(false)
        });
    })
}
Template.entitiesList.helpers({
    entities:function(){return Entities.find()}
    isLoading:function(){Template.instance().isLoading.get()
    isFirstLoading:function(){Template.instance().isFirstLoading.get()
})


<template name="entitiesList">
  <div class="entities">
    <h1>Entities list</h1>
    {{#if isFirstLoading}}
       <p>Looking up...<p/>
       {{>spinner}}
    {{else}}
        {{#each entities}}
            {{> entityItem}}
        {{else}}
            <p>No entity found</p>
        {{/each}}
        {{#if isLoading}}
            {{>spinner}}
        {{/if}}
    {{/if}}
  </div>
</template>
Template.entitiesList.created=function()
{
var self=这个
this.isload=new ReactiveVar(false)
this.isFirstLoading=new ReactiveVar(true)
this.autorun(函数(){
self.isLoading.set(真)
subscribe('entities',{lat:Session.get('lat'),lon:Session.get('lon')},函数(err){
self.isLoading.set(false)
self.isfirstload.set(false)
});
})
}
Template.entitiesList.helpers({
实体:函数(){return entities.find()}
isLoading:function(){Template.instance().isLoading.get()
isFirstLoading:function(){Template.instance().isFirstLoading.get()
})
实体列表
{{#如果是第一次加载}
正在查找…

{{>微调器} {{else} {{{#每个实体}} {{>entityItem} {{else} 找不到实体

{{/每个}} {{{#如果正在加载} {{>微调器} {{/if} {{/if}
通过摆弄iron router,我发现实际上有一个选项,可以不在每次触发的新订阅上呈现加载模板:。只需用
订阅替换
waitOn
,我就得到了想要的结果。

非常感谢!正是我想要的:一个干净的黑客:)我刚刚添加了一个
els将
语句添加到
每个
块,以便在区域中找不到实体时显示通知。