在Meteor中创建一个响应式模板助手

Making a template helper reactive in Meteor

本文关键字:响应 一个 Meteor 创建      更新时间:2023-09-26

我正在构建一个聊天应用程序,在我的"新聊天"页面上我有一个联系人列表,您可以通过点击它们逐个选择(在此基础上,我应用CSS选择类并将用户id推送到一个名为'newChatters'的数组中)。

我想让这个数组对一个助手方法可用,这样我就可以显示一个响应式的名称列表,其中包含所有已添加到聊天中的用户。

我想在其中显示响应列表的模板:

<template name="newChatDetails">
  <div class="contactHeader">
    <h2 class="newChatHeader">{{newChatters}}</h2>
  </div>
</template>

选中联系人时触发的click contactItem事件:

Template.contactsLayout.events({
 'click #contactItem': function (e) {
   e.preventDefault();
   $(e.target).toggleClass('selected');
   newChatters.push(this.username);
...

newChatters数组正在正确更新,所以到目前为止一切正常。现在我需要使{{newChatters}}响应更新。这是我尝试过的,但它不正确,不工作:

Template.newChatDetails.helpers({
  newChatters: function() {
    return newChatters;
  }
});

我如何以及在哪里使用Deps.autorun()使此工作?我甚至需要它,因为我认为助手方法自动更新无效?

1)在定义对象的位置定义Tracker.Dependency:

var newChatters = [];
var newChattersDep = new Tracker.Dependency();

2)在读取对象之前使用depend():

Template.newChatDetails.newChatters = function() {
  newChattersDep.depend();
  return newChatters;
};

3)使用changed()后写:

Template.contactsLayout.events({
  'click #contactItem': function(e, t) {
    ...
    newChatters.push(...);
    newChattersDep.changed();
  },
});

您应该使用Session对象。

Template.contactsLayout.events({
 'click #contactItem': function (e) {
   //...
   newChatters.push(this.username);
   Session.set('newChatters', newChatters);
 }
});

Template.newChatDetails.helpers({
  newChatters: function() {
    return Session.get('newChatters');
  }
});

您可以使用本地Meteor.Collection游标作为响应性数据源:

var NewChatters = new Meteor.Collection("null");

模板:

<template name="newChatDetails">
  <ul>
    {{#each newChatters}}
      <li>{{username}}</li>
    {{/each}}
  </ul>
</template>
事件:

Template.contactsLayout.events({
  'click #contactItem': function (e) {
    NewChatters.insert({username: this.username});
  }
});

助手:

Template.newChatDetails.helpers({
  newChatters: function() { return NewChatters.find(); }
});

要模仿Session的行为而不污染Session,请使用ReactiveVar:

 Template.contactsLayout.created = function() {
      this.data.newChatters = new ReactiveVar([]);
 }
 Template.contactsLayout.events({
      'click #contactItem': function (event, template) {
            ...
            template.data.newChatters.set(
                template.data.newChatters.get().push(this.username)
            );
           ...

然后在内部模板中,使用父响应数据源:

 Template.newChatDetails.helpers({
      newChatters: function() {
           return Template.parentData(1).newChatters.get();
      }
 });

对于在2015+年寻找解决方法的人(因为该职位是2014年)。

我正在实现一个帖子向导pw_module,我需要根据路由参数响应地更新数据:

Router.route('/new-post/:pw_module', function(){
    var pwModule = this.params.pw_module;
    this.render('post_new', {
        data: function(){
            switch (true) {
                case (pwModule == 'basic-info'):
                    return {
                        title: 'Basic info'
                    };
                    break;
                case (pwModule == 'itinerary'):
                    return {
                        title: 'Itinerary'
                    };
                    break;
                default:
            }
        }
    });
}, {
    name: 'post.new'
});

之后在模板中执行a:

<h1>{{title}}</h1>

改变路线

更新URL的导航如下所示:

<nav>
    <a href="{{pathFor route='post.new' pw_module='basic-info'}}">Basic info</a>
    <a href="{{pathFor route='post.new' pw_module='itinerary'}}">Itinerary</a>
</nav>

希望还能帮到一些人。