2016-04-16 8 views
1

Meteor.callまたはMeteor.applyにはクライアント側のスタブを実行し、サーバーメソッドを呼び出さないように指示する方法はありますか?クライアントでのみメテオのメソッドを呼び出す

たとえば、ToDoリストの例があるとします。多分私達は匿名(ログインしていない)ユーザーがいくつかのデフォルトのタスク表示する:

  • を一
  • あなた自身を追加します。名前を変更
  • タスクをチェックしてみてくださいをアカウントに
を作成します。

ログインしたユーザーにはタスクが表示され、すべての機能を2回実装する必要はありません(登録済みの場合は1回、anonの場合は1回) ymousユーザー)。

これが通常の方法で実装されている場合、Meteorはすべての接続されたクライアントに変更をプッシュします。つまり、すべての匿名ユーザーは同じタスクを共有し、他のユーザーの編集内容をリアルタイムで表示します。

匿名ユーザーごとに独自のタスクを追加すると、無駄なものがデータベースに残ります。

私はクライアント側でメソッドを実行する方法を探していますif (!Meteor.user())

+1

なぜ複雑になるのですか?必要な機能を作成して直接呼び出すのはなぜですか?一貫性のためにメソッドスタブ内で同じ関数を引き続き使用できます。 –

+0

どういう意味ですか?インターフェイスはTasksコレクションをレンダリングします。タスクコレクションはサーバー上で更新され、クライアントにプッシュダウンされます。 "[...]関数を作成して直接呼び出す"とはどういう意味ですか?どの機能を作成すればいいですか?それを直接呼び出す方法は? – Dominik

答えて

0

これまで様々なアプローチがあります。

ジャストデータベース(とにかく)でこれらのドスを追加します。

これは、アプリケーションに追加のロジックを追加しないため、これを行う最も簡単な方法です(匿名ユーザーのログイン時にアプリケーションにデータを追加する場合を除く)。

あなたは「データベースを無駄なもので埋める」と言っていますが、それは本当に重要ですか?シェイクスピアのウェイトは約5MBですが、これで何の問題もないでしょう。

このようにすれば、匿名アカウントシステムを追加して、どのユーザーがどのアイテムを所有しているかを参照することができます。 artwells:accounts-guestパッケージをお勧めしますが、他にもいくつかのパッケージがあります。

クライアント専用のコレクションを使用してください。

DummyTodos = new Mongo.Collection('dummy-todos'); 
あなたはこのコードは唯一のクライアント側で実行されていることを確認したい

ので、次のいずれか

  • if(Meteor.isClient)でそれを囲みます。
  • または/your-root-project/clientのファイルに入れてください。

しかし、その後、あなたがドスを扱うすべての場所でより多くのロジックを追加する必要があります:あなたは、非常に多くのロジックがあることを見ることができます

Meteor.methods({ 
     'todo.setChecked'(todoId, isChecked) { 
     check(todoId, String); 
     check(isChecked, Boolean); 
      var todo = Todos.findOne(todoId); 
      var todoClass = Todos; 

      if(!todo && Meteor.isClient){ 
       todo = DummyTodos.findOne(todoId); 
       todoClass = DummyTodos 
      } 

      if(todo) { 
       todoClass.update(todoId, { $set: { checked: isChecked } }); 
      } else if(Meteor.isClient){ 
       // On the server side, you don't know whether something went wrong, or it was just a local todo 
       // So you're losing some error handling here, which isn't good 

       // You can still deal with this on the client-side, maybe you want to: 
       throw "No todo with id " + todoId; 
       // or just 
       return; 
       // But the server will fail silently, so you're losing error handling 
      } 

     }, 
    }); 

、あなたは次のように、関数内でそれを包むことができ:

var getTodoOrDummyTodo: function(todoId) { 
     var todo = Todos.findOne(todoId); 

     if(!todo && Meteor.isClient){ 
      todo = DummyTodos.findOne(todoId); 
     } 

     // I return some todo, but I don't know where it comes from 
     if(todo) 
      return todo; 
     else 
      throw "Well, something wrong happened but I'm not sure what" 
    } 

しかし、あなたは他の問題がある参照(TODOはどこから来るのかがわからない、あなたは、サーバー側で制御することはできません...)。また、ドスは(のように、「isDummy」フィールドを追加フラグ可能性:

Meteor.methods({ 
     'todo.setChecked'(todoId, isChecked) { 

しかし、再び、これはあなたがどこでもこのフラグを見てする必要があります意味それは将来の証拠ではありません

使用平野。 JavaScriptのオブジェクトや関数は

私は、これはキリスト教-フリッツ@あなたの質問にコメントで示唆するものだと思うあなたは、プレーンJavaScriptのオブジェクトを使用すると、あなたとコレクションそれらをマージできます。

var dummyTodos = [ 
     {text: "Hello", checked: true}, 
     {text: "Bye", checked: false} 
    ] 

    var todos = Todos.find(); 
    if(todos.count() < 1){ 
     return dummyTodos; 
    } else { 
     return todos; 
    } 
をあなたは_idフィールドがありますかどうかを確認、直接のtodoオブジェクトを送信し、この(簡体字)のように、それに応じて更新することができ、あなたの流星の方法で

しかし、その後、あなたは、コレクションの反応性を失うことになりますとテンプレート(Tracker Dependencyを使用して自分で実装することもできますが、これはもう単純な方法ではありません)。

TL:DR:これらの例は、類似したオブジェクトに対して2つの異なるデータストアを持つこと、特に異なるAPIを持つ場合に、そのコレクションの「モック」を作成できないことを悪い考え方としています。 mongoコレクションオブジェクトに似ています。 "todos"があなたのアプリで重要なオブジェクトでなかった場合は、私が示したもののような代替を使うことができますが、ここではアプリ全体で10%多くのコードを作成します。したがって、サーバー側のコレクションを使用します。

関連する問題