流星:为什么Iron Router的onBeforeAction被多次调用?

时间:2014-08-02 21:25:37

标签: meteor iron-router

当我在浏览器中访问路径时,我希望Iron Router在加载路由之前调用onBeforeAction一次。但看起来它在首次加载路线时被调用了3次。

这对我来说是一个问题,因为如果用户无权访问该文档,我想放置重定向用户的代码。

onBeforeAction: ->
  console.log 'called once' #Called 3 times when first loading the route!
  thread = Research.findOne(@params._id)
  console.log thread # This is undefined at first run
  thread = Research.findOne(@params._id)
  if thread?
    Meteor.subscribe 'collabUsers', @params._id
  else
    Router.go '/research'

由于它被多次调用,因此会导致重定向问题。具有访问权限的第一个用户也会被重定向,因为第一个线程未定义。

如果检查用户是否可以访问路由所依赖的数据,我想要做什么,如果没有,那么我需要重定向用户。这就是为什么在onBeforeAction中我试图从数据库中提取文档,如果它存在,那么我将加载页面,否则我将重定向或抛出错误信息给用户。

但我注意到onBeforeAction中的console.log语句在首次加载路由时被调用3次。而且在第一次运行时,用户由于某种原因无法访问任何研究线程(我相信订阅尚未设置,并且首次运行时无法访问文档)因此,这会导致我尝试查看是否有访问权限的问题因为在第一次运行时没有人有权访问。

这是整个router.coffee代码

appendUserData = (array) ->
  _.each array, (item) ->
    user = Meteor.users.findOne(item.userId)
    if user?.profile.firstName? && user?.profile.lastName?
      item.firstName = user.profile.firstName
      item.lastName = user.profile.lastName
      item.username = user.username

userEnabled = () ->
  if Meteor.user()
    if $(window).width() > 768
      if !$('.show-left').hasClass 'active'
        Meteor.defer ->
          $('.show-left').click()

requireLogin = (pause) ->
  if !Meteor.user()
    @setLayout 'layoutLoggedOut'
    if Meteor.loggingIn()
      @render @loadingTemplate
    else
      @render 'login'
      pause()
  else
    @setLayout 'layout'
    if window.location.pathname is '/' or undefined
      Router.go('addAndSearchPosts')
    else
      Router.go(window.location.pathname)

Router.configure 
  layoutTemplate: 'layout'
  loadingTemplate: 'loading'
  onBeforeAction: ->
    #this code get which ids we need to get data from to render template. Here we need to get data to notification of collab
    params = {}
    params.threadIds = []
    params.userIds = []
    notifications = Notifications.find {userId: Meteor.userId()}
    notifications.forEach (notification) ->
      params.threadIds.push notification.threadId
      params.userIds.push notification.requesterId

    @subscribe('notificationDataCollab', params).wait()
  waitOn: ->
    [
      Meteor.subscribe 'myResearch', Meteor.userId()
      Meteor.subscribe "notifications"
    ]


Router.onAfterAction userEnabled
Router.onBeforeAction requireLogin,
  except: 'template1'
Router.onBeforeAction 'loading'
Router.onBeforeAction ->
  Errors.clearSeen()

Router.map ->
  @route 'posts_page',
    path: '/posts',
  @route 'template1',
    path: '/template1',
  @route 'login',
    path: '/',
  @route 'addAndSearchPosts',
    path: '/bookmarks',
    waitOn: ->
      Meteor.subscribe 'myBookmarks', Meteor.userId()
    data: ->
      bookmarks: Bookmarks.find
        _userId: Meteor.userId()
  @route 'research',
    path: '/research/:_id',
    waitOn: ->
      [
        Meteor.subscribe 'threadNotes', @params._id, Meteor.userId()
        Meteor.subscribe 'collabUsers', @params._id
      ]
    onBeforeAction: ->
      console.log 'called once'
      #Meteor.subscribe 'collabUsers', @params._id
      # thread = Research.findOne(@params._id)
      # console.log thread
      #thread = Research.findOne(@params._id)
      # if thread?
      #   Meteor.subscribe 'collabUsers', @params._id
      # else
      #   Router.go '/research'
        #Errors.throw('Thread does not exist or you do not have access', false)
    data: ->
      # this code is for appending the user data to pending and current collaborators for this thread
      thread = Research.findOne(@params._id)
      if thread?.pending?.collaborators?.length > 0
        appendUserData(thread.pending.collaborators)
      if thread?.collaborators?.length > 0
        appendUserData(thread.collaborators)
      data = 
        researchThread: thread,
        notes: Notes.find
          _threadId: @params._id
        ,
          sort: 
            date: -1
      data
  @route 'researchHome',
    path: '/research'
  @route 'profileEdit',
    path: '/editprofile'

这是publications.coffee

Meteor.publish 'myResearch', (id) ->
  Research.find({$or: [{_userId: id}, {'collaborators.userId': id}] })


Meteor.publish 'threadNotes', (threadId) ->
  Notes.find({_threadId: threadId})

Meteor.publish 'myBookmarks', (userId) ->
  Bookmarks.find({_userId: userId})

Meteor.publish 'collabUsers', (threadId) ->
  Meteor.users.find({}, {fields: {profile: 1, username: 1}})

Meteor.publish 'notifications', ->
  Notifications.find()

Meteor.publish 'notificationDataCollab', (params) ->
  [
    Meteor.users.find({_id: {$in: params.userIds}}, {fields: {username: 1}})
    Research.find({_id: {$in: params.threadIds}}, {fields: {name: 1}})
  ]

有关如何处理此问题的任何建议表示赞赏。

1 个答案:

答案 0 :(得分:6)

运行

onBeforeAction并重新运行。您可能需要onRun