【问题标题】:Meteor: Why is Iron Router's onBeforeAction called multiple times?Meteor:为什么 Iron Router 的 onBeforeAction 会被调用多次?
【发布时间】:2014-09-25 19:08:28
【问题描述】:

当我在浏览器中访问路由时,我希望 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}})
  ]

感谢任何有关如何处理此问题的建议。

【问题讨论】:

    标签: meteor iron-router


    【解决方案1】:

    onBeforeAction 以反应方式运行并重新运行。你可能想要onRun

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-21
      • 1970-01-01
      • 2015-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多