2014-10-21 2 views
3

Мне интересно, как получить доступ к предыдущему элементу в цикле {{#each items}}. Например Template.index.messages возвращает массив объектов с именем и сообщением:Доступ к предыдущему элементу в {{#each}} loop

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

В основном я хотел бы, чтобы скрыть имя в последовательных сообщений. Я сделал обходной путь, фильтруя сообщения в Template.index.messages, но этот метод вызывается каждый раз, когда изменения данных и, следовательно, стоят много ресурсов. Итак, как это сделать в космос?

Заранее спасибо.

ответ

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; 
    } 
}); 
1

Вы можете использовать https://github.com/raix/Meteor-handlebar-helpers когда они принимают мой запрос на тягу https://github.com/raix/Meteor-handlebar-helpers/pull/65

В противном случае вы можете добавить это своим помощникам проекта, чтобы имитировать $ Сопоставляются поведение

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 || []; 
}); 

Использование

{{#each $mapped yourCursor true}} 
//Getting the next & previous element 
{{$nextEl._id}} 
{{$prevEl._id}} 
{{/each}} 
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); 
    } 
}); 

Без дополнительной базы хранения или обхода не требуется.

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, ../ на самом деле пошел на один шаг выше иерархии, а затем получить доступ поля, если имеется, поскольку Клиент уже доступен для шаблона, это поле подбирается. Аналогично, если есть сбор выше Клиент, вы можете использовать ../../rechargeplan

Смежные вопросы