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>

很奇怪的行为。这些按钮不会更新数据。如果我更改一点代码,服务器就会刷新,有时我会得到一个更新。然后点击更多按钮,但没有 UI 更改。尝试在点击处理程序中添加 Deps.refresh 但没有运气。

看起来只修改服务器代码真的会强制刷新......也许是 UI 问题而不是数据问题?PS如何在浏览器中查看数据

4

2 回答 2

1

感谢邮件列表:

Avital 奥利弗 7 月 27 日上午 10:04 -0700

尝试 {shipto: re} 而不是 {shipto : {$regex: re}}。(我认为这是我们两天前在 devshop 发现的一个错误)

第一个答案当然是订阅的正确方法。然而,它还是坏了。这修复了最后一部分。

发帖帮助其他可怜的灵魂...

于 2013-07-28T15:23:57.180 回答
1

正确的订阅方式是:

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

如果您尝试过此操作但它不起作用,则错误在其他地方。

 


 

为了使反应性起作用,您需要两件事:自动运行上下文和反应性数据源。

自动运行上下文是一种监视一个或多个依赖项并在其中一个发生更改时重新运行的函数。在这种情况下,它是由Deps.autorun函数提供的。

反应式数据源是一个能够通知上下文它已更改其值的对象。在上述情况下,它是 Session 变量。

您不能仅对这些因素之一产生反应,要使函数自动重新运行,您需要同时提供两者。

于 2013-07-26T19:45:39.167 回答