2014-11-14 79 views
1

我想設置一個Session變量(artistNotAvailable),當請求的藝術家不可用。不幸的是,這條路線不起作用,因爲它不會在我的onBeforeAction掛鉤中等待訂閱數據。 artistAvailartist未定義,但不是因爲數據庫中沒有藝術家,我認爲這是訂閱問題。我調試它並在瀏覽器控制檯中調用Artists.find().fetch();返回undefined流星 - 鐵路由器不等待onBeforeAction掛鉤訂閱數據

這裏是我的路線:

this.route('eventPage', { 
     path: '/event/:slug/:openDate?/:closeDate?', 
     onBeforeAction: [teamFilter, function() { 
      var event = this.data(); 
      if (event.outdoor) { 
       this.subscribe('artists', this.params.slug); 
       if (this.ready()) { 
        var artistAvail = Artists.findOne({eventId: event._id, openDate: moment(this.params.openDate).toDate(), closeDate: moment(this.params.closeDate).toDate()}); 
        if ((!this.params.openDate && !this.params.closeDate) || typeof artistAvail === "undefined") { 
         var artist = Artists.findOne({ 
          eventId: event._id, 
          openDate: {$lte: new Date()}, 
          closeDate: {$gte: new Date()} 
         }); 
         if (Artists.find().count() > 0 && artist) { 
          Session.set('artistNotAvailable', true); 
          this.redirect('eventPage', { 
           slug: this.params.slug, 
           openDate: moment(artist.openDate).format('YYYY-MM-DD'), 
           closeDate: moment(artist.closeDate).format('YYYY-MM-DD') 
          }); 
         } else { 
          Session.set('noArtists', true); 
          this.redirect('overviewPage', {slug: this.params.slug}); 
         } 
        } else { 
         this.subscribe('musicOutdoor', this.params.slug, moment(this.params.openDate).toDate(), moment(this.params.closeDate).toDate()); 
         if (this.ready()) { 
          var guestsIds = new Array(); 
          Guests.find({artistId: artistAvail._id}).forEach(function (guest) { 
           guestIds.push(guest._id); 
          }); 
          this.subscribe('guestsOutdoor', guestIds); 
         } else { 
          this.render('loading'); 
         } 
        } 
       } else { 
        this.render('loading'); 
       } 
      } else { 
       this.subscribe('musicIndoor', this.params.slug); 
       this.subscribe('guestsIndoor', this.params.slug); 
       if (!this.ready()) { 
        this.render('loading'); 
       } 
       this.next(); 
      } 
      this.next(); 
     }], 
     waitOn: function() { return [Meteor.subscribe('singleEvent', this.params.slug)]; }, 
     data: function() { 
      return Events.findOne({slug: this.params.slug}); 
     } 
    }); 

訂閱:

Meteor.publish('artists', function(slug) { 
    var event = Events.findOne({slug: slug}); 
    if (event) { 
     return Artists.find({eventId: event._id}); 
    } else { 
     return null; 
    } 
}); 

現在的問題是,當我用錯了openDatecloseDate訪問eventPage我會被重定向到overviewPage,甚至儘管db中有藝術家。如前所述,我調試它,它似乎是this.ready()不起作用。 我真的很想念.wait() :-(

任何幫助,將不勝感激。

+1

這是一個路線裏面大量的工作。 我更喜歡在onBefore中訂閱所有需要的集合,並將主要數據發送到模板,然後使用該模板上的助手來執行「控制器」作業。儘管它迫使我在大多數子集合中放置如此​​外部的_id ... – Guidouil 2014-11-14 23:14:20

+1

在鐵路路由器中,我想動態訂閱你把它們放在'waitOn'中的東西嗎?那就是我一直在做的事情,而且似乎有效。除此之外,你可以把它放在你的模板創建和退訂銷燬。另外,如果你想在模板中設置'this',你可以在'data'中返回你想要的任何對象。當我需要將一個模板掛鉤到一個'Collection.find()'或'Collection.findOne()'的結果中時,我會使用它。 – CodeChimp 2014-11-15 01:01:56

+0

感謝您的幫助。@Guidouil如果可能的話,我想保留'onBeforeAction'中的邏輯。 @CodeChimp我無法訂閱'waitOn'中的所有內容,因爲它取決於可以使用訂閱的'event.outdoor'。這可能是一個問題,因爲'this.next()'。我已經問過它如何正確工作,但我仍然困惑於正確放置的位置。基本上它應該工作,問題是'this.ready()'是真的,但事實上它不是。 – user3475602 2014-11-15 07:41:44

回答

4

鐵路由器工作正常。

this.subscribe就像Meteor.subscribe和鐵路由器沒有按」迫不及待了這一點。

waitOn是將等待的函數,直到每個返回訂閱的準備,這就是爲什麼this.ready()是真的在onBeforeAction

有你想要

  • 你可以不喜歡它CodeChimp說通過使用模板創造出什麼做的幾種方法/毀
  • 你可以在不同路線上分割您的路線,以便在需要時重定向
  • 您可以使用。等待()來自鐵路路由器here的新API。
+0

謝謝你的幫助。用this.wait替換'this.subscribe('artists',this.params.slug);''會產生一個異常。此外,我得到這樣的警告:'路由派遣從不渲染。你忘了在onBeforeAction中調用this.next()?'我應該在哪裏放置'this.next()'? – user3475602 2014-11-18 20:20:10

+0

我把訂閱放在我的'waitOn'函數中,並改變了我的'publish'邏輯。謝謝! – user3475602 2014-11-18 20:54:52

0

它幫助我在數據功能等待訂閱(直到訂閱是真的準備好了),就像這樣:

Router.route('/:_id', { 
    name: 'show', 
    template: 'show', 
    waitOn: function() { 

     var id = this.params._id; 
     return Meteor.subscribe('something', id, {}); 
    }, 
    data: function() { 

     if (this.ready()) { 
      var id = this.params._id; 
      var data = Somethings.findOne({_id: id}); 
      return data; 
     } 
    } 
});