0

meteorjs のパブリッシュとサブスクライブを理解しようとしています。私は動的公開機能を書きました:

Meteor.publish("customers",function(f) {
  var re=null;
  if ('undefined' !== typeof f) {
    re = new RegExp("^"+f,"i");
  }
  return customers2.find({$and: [{shipto: {$ne:""}}, {shipto: {$regex: re}}]},{sort: {shipto:1}});
});

これにより、特定の文字で始まるすべての顧客が取得されます。

次に、起動時にサブスクライブします。

Meteor.subscribe("customers","");

すべての顧客を表示します。これで、顧客ページにこのイベント関数を指す入力ボックスができました。

function filterCustomers(e,t) {
  var f = $(e.target).val();
  Meteor.subscribe("customers",f);
}

新しいサブスクリプションは、顧客リストをまったく更新していないようです。

次に、起動時に試しました

Meteor.subscribe("customers",Session.get("customer_filter"));

これはフィルター関数で:

function filterCustomers(e,t) {
  var f = $(e.target).val();
  Session.set('customer_filter',f);
}

ただし、セッション変数を更新してもパブリッシュは更新されません。

サブスクライブを Deps.autorun に入れましたが、それは役に立ちませんでした。

顧客データベース全体を送信しないようにしています。サブスクライブが更新されないのはなぜですか? そのために何をしなければなりませんか?パブリッシュとサブスクライブについてわからないことは何ですか?


以下の提案に従って、単純なアプリを抽出しました。

Customers = new Meteor.Collection("customers");

if (Meteor.isClient) {

Session.setDefault("customer_filter","");

Deps.autorun(function () {
  Meteor.subscribe('customers',Session.get('customer_filter'));
});

Template.customers.events({
  'click .dof' :function(e,t) {
    Session.set("customer_filter", $(e.target).attr("find"));
  }
});

Template.customers.customers = function() {
  return Customers.find();
}

Template.customers.currentFilter = function() {
  return " | "+Session.get("customer_filter");
};

}

if (Meteor.isServer) {
// Publish complete set of lists to all clients.
  Meteor.publish('customers', function (filter) {
    var re=null;
    if (filter) {
      re = new RegExp("^"+filter,"i");
     }
     return Customers.find({$and:[{shipto: {$ne:""}},{shipto: {$regex: re}}]},{sort:{shipto:1}});
  });

}

そしてテンプレ

<body>
  {{> customers}}
</body>

<template name="customers">
  <h2>Customer List {{currentFilter}}
  <div id="custom-search-form" class="form-search form-horizontal pull-right">
    <div class="input-append">
        <input type="text" class="search-query span6" placeholder="Search">
        <button type="submit" class="btn"><i class="icon-search"></i></button>
    </div>
</div>
</h2>
<button find="" class="dof">ALL</button>
<button find="f" class="dof">F</button>
<button find="g" class="dof">G</button>
<button find="h" class="dof">H</button>
<button find="i" class="dof">I</button>
<button find="j" class="dof">J</button>

<table class="table table-striped" border=1>
  <thead>
  <tr>
    <th>Ship To</th>
    <th>Address</th>
    <th>Attn</th>
      </tr>
    </thead>
    <tbody>
    {{#each customers}}
      <tr>
        <td>{{shipto}}</td>
        <td>{{address}}, {{city}}, {{state}} {{zip}}</td>
        <td>{{attn}}</td>
      </tr>
    {{/each}}
    </tbody>
  </table>
</template>

非常に奇妙な振る舞い。ボタンはデータを更新しません。少しコードを変更すると、サーバーが更新され、更新が 1 つ取得されることがあります。その後、さらにボタンがクリックされますが、UI は変更されません。クリック ハンドラに Deps.refresh を追加しようとしましたが、うまくいきませんでした。

サーバーコードを変更するだけで本当に更新が強制されるように見えます...データの問題ではなく、UIの問題でしょうか? PS ブラウザでデータを表示するにはどうすればよいですか

4

2 に答える 2

1

サブスクライブする正しい方法は次のとおりです。

Deps.autorun(function(){
    Meteor.subscribe('customers', Session.get('customer_filter'));
});

これを試してもうまくいかない場合、エラーは別の場所にあります。

 


 

リアクティブが機能するには、自動実行コンテキストとリアクティブ データ ソースの 2 つが必要です。

自動実行コンテキストは、1 つまたは複数の依存関係を監視し、それらのいずれかが変更されるたびに再実行される関数です。この場合、Deps.autorun関数によって提供されます。

リアクティブ データ ソースは、値が変更されたことをコンテキストに通知できるオブジェクトです。上記の場合、それはセッション変数です。

これらの要因の 1 つだけに反応性を持たせることはできません。関数を自動的に再実行するには、両方を提供する必要があります。

于 2013-07-26T19:45:39.167 に答える