2014-12-02 63 views
0

所以,這裏有一個問題:我使用this neat solution存儲用戶的座標。下面是我的實現:對會話更改產生反應的訂閱會導致每個實體都重繪每個實體

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> 

Now!此解決方案有效。實體被正確列出,根據用戶的位置每5秒更新一次。

唯一的問題在於渲染:當反應性由於會話變量的更新而導致整個實體集合被刪除並重新繪製時。但是,當實體集合中發生更改(例如,實體被刪除/創建)時,只會在模板中重新呈現此更改。

這產生了一個列表,每5秒閃爍一次非常惱人的列表。我想刪除#each塊,並使用在rendered函數中自己編寫它,並使用jQuery以更優化的方式重新繪製列表,但這會是一個令人討厭的黑客攻擊,HTML代碼塊外部的模板文件...當然,還有另一種方式!

回答

1

每當你改變你的會話變量,你的訂閱正在加載,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> 
+0

非常感謝!究竟是我在找什麼:乾淨的黑客:)我只是在'each'塊中添加一個'else'語句,以便在該區域中找不到實體時顯示通知。 – SylvainB 2014-12-03 12:18:24

0

通過與鐵路由器擺弄,我發現這裏居然是不渲染加載模板在每一個新的訂閱觸發一個選項:the subscriptions option。只需要用subscriptions代替waitOn,我就可以得到想要的結果。

相關問題