2016-04-04 1 views
1

Я работаю над многопользовательским приложением, и я не уверен, как загружать маршруты условно.Iron Router - Условные маршруты в зависимости от арендатора

Я имел:

var tenant = resolveTenant(); 
    if (tenant === null) { 

     Router.configure({ 
      layoutTemplate: 'main', 
      notFoundTemplate: 'not-found' 
     }) 
     Router.route('home', { 
      path: '/' 
     }) 

     Router.route('newClient', { 
      path: 'signup' 
     }) 
    } else { 
     Router.configure({ 
      layoutTemplate: 'storeMain', 
      notFoundTemplate: 'not-found' 
     }) 
     Router.route('storeHome', { 
      path: '/' 
     }) 
    } 

Так, если арендатор не может быть решен, загрузите основной сайт.

Это работало отлично, не красиво, но прекрасно. Однако проблема заключается в том, что арендатор не существует.

Корпус:

Для этого мне нужно позвонить в базу данных. Поэтому я завернул условие внутри метод вызова с обратным вызовом:

Router.configure({ 
     layoutTemplate: "loading" 
    }); 
    var tenant = resolveTenant(); 
    Meteor.call("tenant.exists", tenant, function(err, exists) { 
     if (tenant !== null && !exists) { 
      Router.configure({ 
       layoutTemplate: 'noTenant' 
      }) 
      Router.route('noTenant', { 
       path: '/' 
      }) 
     } else if (tenant === null) { 

      Router.configure({ 
       layoutTemplate: 'main', 
       notFoundTemplate: 'not-found' 
      }) 
      Router.route('home', { 
       path: '/' 
      }) 

      Router.route('newClient', { 
       path: 'signup' 
      }) 
     } else { 
      Router.configure({ 
       layoutTemplate: 'storeMain', 
       notFoundTemplate: 'not-found' 
      }) 
      Router.route('storeHome', { 
       path: '/' 
      }) 
     } 
    }) 

Проблема заключается в том, это не будет переходить от конфигурации шаблона загрузки после того, как вызов завершен. И если я удалю маршрут шаблона загрузки, я получаю целевую страницу железного маршрутизатора.

Для завершения, здесь "tenant.exists" метод:

"tenant.exists": function(url){ 
    if(url === null){ 
     return false 
    } 
    return Tenants.find({"url": url}).count() > 0; 
    }, 

Любые идеи о том, как достичь этого?

Редактировать

Я попытался удалить условия из вызова метода и выполнения запроса на стороне клиента. Однако счетчик всегда возвращал 0, когда он не должен.

if (tenant !== null && Tenants.find({"url": tenant}).count() === 0) { 
     Router.configure({ 
      layoutTemplate: 'noTenant' 
     }) 
     Router.route('noTenant', { 
      path: '/' 
     }) 
    } else if (tenant === null) { 

     Router.configure({ 
      layoutTemplate: 'main', 
      notFoundTemplate: 'not-found' 
     }) 
     Router.route('home', { 
      path: '/' 
     }) 

     Router.route('newClient', { 
      path: 'signup' 
     }) 
    } else { 
     Router.configure({ 
      layoutTemplate: 'storeMain', 
      notFoundTemplate: 'not-found' 
     }) 
     Router.route('storeHome', { 
      path: '/' 
     }) 
    } 
+0

У меня сложилось впечатление, что в вызове метода может возникнуть какая-то проблема ..вы могли отлаживать и видеть, отвечает ли вызов метода, как вы ожидаете? –

+0

Да все как и ожидалось, возвращает true, если существует, false, если нет. Я попытался удалить условия из вызова метода и сделал «Tenants.find» ({«url»: tenant}). Count() === 0', но вызов продолжал возвращать true (так как ни один арендатор, найденный с этим URL-адресом), любые идеи о том, почему это было бы? Я слишком долго не делал Метеор. –

+0

Если вы выполняете запрос на стороне клиента, есть ли там вся коллекция Tenants? Просто попробуйте запросить коллекцию в консоли браузера и проверьте, что там публикуется: Tenants.find(). Fetch(); –

ответ

1

Пожалуйста, позвольте мне предложить гораздо более простой подход, который также позволяет избежать публикаций имен всех вас арендаторов к каждому клиенту, а также избегая асинхронные побочные эффекты Meteor.call():

  1. Подписаться на подписка арендатора, передающая имя арендатора в качестве параметра
  2. В соответствующей публикации просто верните один соответствующий арендатор
  3. В обработчике onBeforeAction посмотрите, есть ли запись арендатора a t все и действуйте, если это так, в противном случае отобразите соответствующую страницу.

Маршрутизатор:

var tenant = resolveTenant(); 

Router.route('/',{ 
    name: 'storeHome', 
    onBeforeAction: function(){ 
    if (Tenants.findOne()) this.next(); 
    else if (tenant) this.render('noTenant'); 
    else this.render('signup'); 
    }, 
    waitOn: function(){ 
    return Meteor.subscribe('tenant', tenant); 
    } 
}); 

Сервер:

Meteor.publish('tenant',name,function(){ 
    check(name,String); 
    return Tenants.find({ url: tenant }); 
}); 

Взятые из моделей here.

+0

Хороший ответ Мишель. Я рассмотрю это. В конце концов, я получил свою работу с Meteor.call. Я пошел с FlowRouter для 'FlowRouter.wait()' и 'FlowRouter.initialize()', когда вызов завершился. Однако ваше решение гораздо более деликатное и решит мою проблему, как указано в моем вопросе. Поэтому я буду отмечать это как ответ. –

Смежные вопросы