访问{{#each}}循环中的上一个元素

时间:2014-10-21 07:46:40

标签: meteor meteor-blaze spacebars

我想知道如何访问{{#each items}}循环中的前一个元素。 例如,Template.index.messages返回带有名称和消息的对象数组:

{{#each messages}}
  {{#if previousMessage.name != this.name }}
    {{name}}
  {{/if}}
  {{this.message}} 
{{/each}}

基本上我想在连续的消息中隐藏名称。我通过过滤Template.index.messages中的消息来解决方法,但每次数据更改时都会调用该方法,因此会占用大量资源。那么,如何在空格键中做到这一点?

提前致谢。

4 个答案:

答案 0 :(得分:1)

您可以在接受我的拉取请求时使用https://github.com/raix/Meteor-handlebar-helpers https://github.com/raix/Meteor-handlebar-helpers/pull/65

否则您可以将其添加到项目助手中以模拟$ mapped行为

select *, (select id from internal_table where internal_table.id =
outer_table.internal_table_id limit 1) as internal_table_id from outer_table;

用法

UI.registerHelper("$mapped", function(arr, extended) {
    var extended = extended || false;
    if(!Array.isArray(arr)){
      try {
        arr = arr.fetch()
      }
      catch (e){
        console.log("Error in $mapped: perhaps you aren't sending in a collection or array.")
        return [];
      }
    }

    var $length = arr.length;

    var mappedArray = arr.map(function(item,index) {
      var newItem = _.clone(item);
      newItem.$length = $length;
      newItem.$index = index;
      newItem.$first = index === 0;
      newItem.$last  = index === $length-1;
      newItem.$index = index;
      if (extended) {
        newItem.$nextEl = arr[index+1];
        newItem.$prevEl = arr[index-1];
        newItem.$firstEl = arr[0];
        newItem.$lastEl = arr[$length-1];
      }
      return newItem;
    });

    return mappedArray || [];
});

答案 1 :(得分:0)

Spacebars模板语言并非真正针对复杂的逻辑构建,因此我不会尝试在模板本身中直接执行此操作。无论你在哪里实现名称隐藏代码,它都会使用资源 - 所以在你好的辅助函数中执行它可能是最简单/最好的方法。作为旁注,spacebars不处理像!=这样的等式语句,你必须为它做一个辅助函数。

如果您真的关心计算时间,减少它的唯一方法是在数据库中存储更多数据(例如最后一条消息的名称)。如果你存储它(例如,在.previousName中),它将如下:

在模板中:

{{#each messages}}
    {{#if notEqual previousName name}}
        {{name}}
    {{/if}}
    {{message}}
{{/each}}

在javascript中:

Template.index.helpers({
    notEqual: function (string1, string2) {
        return string1 !== string2;
    }
});

答案 2 :(得分:0)

我将提供一个不同的答案,不涉及在数据库中添加更多信息。之所以能有点毛茸茸的原因是,如果由于某种原因它所指的“以前的名字”不再存在,那么你的模板逻辑就会关闭。然后,您必须确保在数据库中删除(或禁用)该记录时,您更改了引用它的所有记录的“先前名称”字段。这可能是一种痛苦。这是我的建议,无需额外的包或数据。

您可以使用@index

访问模板中任何数组的索引

所以你可以在模板中这样做:

{{#each messages}}
  {{#if isSameName @index}}
    {{name}}
  {{/if}}
  {{this.message}} 
{{/each}}

然后在你的助手中:

Template.index.helpers({
    isSameName: (idx) => {
        // Get the messages from your local storage
        let msgs = Messages.find().fetch();
        // Lets make sure we don't get any errors from the previous message not existing
        return (msgs && msg[idx-1] && msgs[idx-1].name === msgs[idx].name);
    }
});

无需额外的数据库存储或遍历。

答案 3 :(得分:0)

您可以使用以下代码来获取外部集合。

假设您有一个名为 Collection.Customer Collection.RechargePlan 的集合,并且您在模板中使用这两个集合来更新客户。

Customer = {"name":"James", "rechargeplan":"monthly"};
RechargePlan = [{"rechargeplan": "monthly"},{"rechargeplan": "yearly"}];

 //Inside template, Bydefault Customer is available.
{{#each RechargePlan}}
  {{#if equals ../rechargeplan rechargeplan}}
      //Hurray Plan matches
  {{/if}}
{{/each}}

在上面的代码中, ../ rechargeplan 实际上是 Customer.rechargeplan ,.. /实际上比heirarchy高出一步,然后访问该字段(如果可用),因为客户已经可用于模板,它的字段被选中。同样,如果客户上方有集合,您可以使用../../ rechargeplan