【问题标题】:iron-router restrict admin access with hooksIron-router 使用钩子限制管理员访问
【发布时间】:2014-12-09 10:18:05
【问题描述】:

我的 Iron-router 有问题。

当我第一次加载页面 /admin/deps 时,路由会正常工作。然后我通过单击链接转到任何其他页面,然后在控制台中返回 /admin/deps/ 我得到“路由调度从未呈现。您是否忘记在 onBeforeAction 中调用 this.next()? "并且模板没有呈现

但是 .. 如果我使用热交换代码更改代码中的任何内容,流星会重新加载页面,在这种情况下,一切都会按预期工作。

这是我的控制器和路由:

class @AdminRouteController extends RouteController
  onBeforeAction: ->
    console.log "onBeforeAction: #{@url}"
    if Meteor.loggingIn()
      @render 'loading'
    else if !Meteor.userId() or !Meteor.user().hasAccess 'admin'
      @render 'notFound'
    else
      @next()

class @AdminPagebleRouteController extends AdminRouteController
  pageable: true 
  perPage: 20    

  limit: (name = null) ->
    Session.get(varName(@, name)) || @perPage

  incLimit: (name = null, inc = null) ->
    inc ||= @perPage
    Session.set varName(@, name), (@limit(name) + inc)

  resetLimit: (name = null) ->
    Session.set varName(@, name), null

  loaded: (name = null) ->
    true

  onRerun: ->
    console.log "onRerun: #{@url}"
    @next()

Router.route '/admin', name: 'admin'
class @AdminController extends AdminRouteController
  template: 'adminHome'
  action: ->
    document.title = i18n 'admin.title'
    super()

Router.route '/admin/deps', name: 'deps'
class @DepsController extends AdminPagebleRouteController
  template: 'deps'
  perPage: 20

  waitOn: ->
    @subscribe 'adminDeps', @limit()

  data: ->
    deps: DepartmentsCollection.find()

  loaded: ->
    @limit() > DepartmentsCollection.find().count()

  action: ->
    document.title = i18n 'deps.title'
    super()

  onRun: ->
    console.log "onRun: #{@url}"
    @resetLimit()
    @next()

  load: ->
    $('html, body').animate({ scrollTop: 0 }, 400)
    $('.content').hide().fadeIn(1000)

这是路由无法正常工作时的控制台屏幕

这是javascript中的代码:

AdminRouteController = RouteController.extend({
  onBeforeAction: function(){
    console.log("onBeforeAction: " + this.url);
    if(Meteor.loggingIn())
      this.render('loading');
    else if(!Meteor.userId() || !Meteor.user().hasAccess('admin'))
      this.render('notFound');
    else
      this.next();
  }
});

varName = function(inst, name){
  name = name && ("_" + name || "");
  return inst.constructor.name + name + "_limit";
}

AdminPagebleRouteController = AdminRouteController.extend({
  pageable: true,
  perPage: 20,

  limit: function (name){
    return Session.get(varName(this, name)) || this.perPage;
  },
  incLimit: function (name, inc){
    inc = inc ? inc : this.perPage;
    return Session.set(varName(this, name), (this.limit(name) + inc));
  },
  resetLimit: function (name){
    return Session.set(varName(this, name), null);
  },
  loaded: function (name){
    return true;
  },
  onRerun: function (){
    console.log("onRerun: " + this.url);
    this.next();
  }
});

Router.route('/admin', name: 'admin');
AdminController = AdminRouteController.extend({
  template: 'adminHome',
  action: function(){
    document.title = i18n('admin.title');
    super();
  }
});

Router.route('/admin/deps', name: 'deps');
DepsController = AdminPagebleRouteController.extend({
  template: 'deps',
  perPage: 20,

  waitOn: function(){
    this.subscribe('adminDeps', this.limit());
  },
  data: function(){
    return { deps: DepartmentsCollection.find() };
  },
  loaded: function(){
    return this.limit() > DepartmentsCollection.find().count();
  },
  action: function(){
    document.title = i18n('deps.title');
    super();
  },
  onRun: function(){
    console.log("onRun: " + this.url);
    this.resetLimit();
    this.next();
  },
  load: function(){
    $('html, body').animate({ scrollTop: 0 }, 400);
    $('.content').hide().fadeIn(1000);
  }
});

【问题讨论】:

    标签: meteor iron-router


    【解决方案1】:

    最后,我找到了答案,问题出在 DepsController 中,在 load() 函数中。在onBeforeAction()之前触发,还需要调用this.next ()

    【讨论】:

      【解决方案2】:

      你能把你的代码放在经典的 Javascript 语法中吗?几乎所有文档都不是您提供的语言,这并不能减轻您获得的支持。

      此外,我想说你的 @AdminRouteController 类的 onBeforeAction 可能有问题。尝试将你的 if/elseif/else 语句分成多个 if,如下所示:

      class @AdminRouteController extends RouteController
        onBeforeAction: ->
          console.log "onBeforeAction: #{@url}"
          if Meteor.loggingIn()
            @render 'loading'
          else 
            @next()
      
          if !Meteor.userId() or !Meteor.user().hasAccess 'admin'
            @render 'notFound'
          else
            @next()
      

      希望这会有所帮助,但我会对经典的 javascript 语法 tbh 更有帮助。

      编辑

      感谢您将代码放入 .js。 通常,当您收到错误“路由调度从未呈现。您是否忘记在 onBeforeAction 中调用 this.next()?”这是因为您忘记在某处的 onBeforeAction() 或 onRun() 中调用 this.next() 。需要弄清楚在哪里......

      干杯,

      【讨论】:

      • 感谢您的回复。我在js中添加了代码。你的建议是一个错误,因为在同一个钩子函数中调用了两次 this.next()
      • 没有我的建议,你的 /admin 路由有同样的问题吗?
      • 不,其他路线工作正常。我尝试在订阅上更改 waitOn,但得到了相同的结果
      • this.next() 在行动中是否必要?此外,你应该考虑重新排序你的钩子的逻辑,这些钩子是混乱的。你用的是 Iron:router 1.0 吗?
      • 我认为有必要采取行动。我不知道如何为非管理员用户呈现特定模板。我用的是最新版本的 Iron Router 1.0.3
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-13
      • 2019-08-11
      • 1970-01-01
      • 2014-03-27
      • 2018-03-20
      • 2015-08-19
      • 2018-11-21
      相关资源
      最近更新 更多