2016-04-04 9 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: '/' 
      }) 
     } 
    }) 

問題があり、通話が終了した後に、それはロードテンプレートの設定から移動しませんです。ロードテンプレートのルートを削除すると、Iron Routerのランディングページが表示されます。これを実現する方法について

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

任意のアイデア:

は、完了のために、ここでは "tenant.exists" 方法とは?

編集

私は、メソッド呼び出しから条件を削除すると、クライアント側でクエリを実行しようとしました。ただし、カウントしない場合は常に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 ":テナント})count()=== 0'を実行しましたが、 )、それはなぜでしょうか?私はあまりにも長い間流星をやっていない。 –

+0

クライアント側でクエリを実行している場合は、Tenantsコレクション全体が公開されていますか?ブラウザコンソールでコレクションのクエリを実行し、そこに公開されているものを確認してください:Tenants.find()。fetch(); –

答えて

1

私もあなたもMeteor.call()の非同期の副作用を回避しながら、すべてのクライアントにすべてのあなたのテナントの名前を公開しないようすることができますはるかに簡単なアプローチを提案することができますしてください:

  1. に登録対応する公報では、パラメータ
  2. としてテナント名を渡しテナントサブスクリプション、単にテナントレコードaがありますかどうかを確認し、onBeforeActionハンドラでは、1個の一致するテナント
  3. を返しますそうでなければ適切なページをレンダリングします。

ルータ:

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()'に行きました。あなたのものは、しかし、はるかにtidier解決策であり、私の質問に概説されるように私の問題を解決するだろう。だから私はこれを答えとしてマークします。 –