Напишите собственный итератор для пробелов

Я пытаюсь написать собственный итератор в пробелах (я использую метеор 1.1.3). Итератор должен быть последовательным циклом for (в основном, чтобы заменить мое использование #each, когда это необходимо, поскольку я считаю, что #each не гарантируется последовательностью в своей итерации).

Я пробовал следующее:

В библиотеке -

UI.registerHelper 'sequentialFor', () ->
  ret = ""
  for i in [[email protected]]
    id = @[i]
    ret = ret + Template.noop
  ret

noop.html -

<template name="noop">
  {{> UI.contentBlock this}}
<template>

основной.html -

{{#sequentialFor ids}}
<div id="wow-{{this}}">stuff</div>
{{/sequentialFor}}

ids в приведенном выше примере — это массив строк, переданных от одного из помощников основного шаблона.

Прямо сейчас он жалуется, что мой помощник по пользовательскому интерфейсу возвращает [object Object] [object Object]. Ради здравомыслия я знаю, что если я заменю свой помощник пользовательского интерфейса на:

UI.registerHelper 'sequentialFor', () ->
  //ret = ""
  //for i in [[email protected]]
    //  id = @[i]
    //  ret = ret + template
  id = @[0]
  Template.noop

Я понимаю, что div в моем main.html отображается с соответствующим идентификатором как часть его атрибута id по желанию. Однако я не могу заставить цикл for работать.

Я не могу просто вернуть div в main.html напрямую из помощника, потому что у меня есть много div, которые мне нужно обернуть с помощью моего нового итератора, каждый из которых имеет очень разные атрибуты.

Я предполагаю, что простой вопрос заключается в том, как мне определить свой собственный итератор блока (похожий на #each) в пробелах?

Более сложный вопрос может заключаться в том, что не так с моим подходом выше?

Я рассмотрел множество ресурсов, но нашел очень полезными только следующие: Как передать объект из помощника блока обратно в блок в метеоре? https://github.com/meteor/meteor/wiki/Using-Blaze https://github.com/meteor/meteor/blob/devel/packages/spacebars/README.md Перебор базового цикла for с использованием Handlebars. js

ПРИМЕЧАНИЕ Я использую coffeescript


person John Cast    schedule 21.04.2015    source источник
comment
каждый не упорядочен, если вы используете сортировку в своем запросе монго?   -  person Eliezer Steinbock    schedule 22.04.2015
comment
Цикл for не работает, потому что this не является массивом.   -  person pfkurtz    schedule 22.04.2015
comment
{{#each}} над массивом будет упорядочено.   -  person user3374348    schedule 22.04.2015
comment
@user3374348 user3374348, насколько мне известно, я не верю, что {{#each}} гарантированно будет последовательным. Смотрите мой комментарий к ответу pfkurtz ниже, чтобы лучше понять мои опасения.   -  person John Cast    schedule 23.04.2015


Ответы (2)


Мне удалось получить собственный итератор, используя рекурсивный метод, аналогичный тому, что вы могли бы использовать в Haskell или Lisp:

<body>
  {{#countdown n=5}}
    <p>item {{this}}</p>
  {{/countdown}}
</body>

<template name="countdown">
  {{#if positive}}
    {{> Template.contentBlock n}}
    {{#countdown n=nMinusOne}}
      {{> Template.contentBlock this}}
    {{/countdown}}
  {{/if}}
</template>
Template.countdown.helpers({
  positive: function () {return this.n > 0;},
  nMinusOne: function () {return this.n - 1;}
});

См. meteorpad.

Производительность, вероятно, намного хуже, чем у обычного {{#each}}.

person user3374348    schedule 23.04.2015
comment
Спасибо за подробный ответ. Я думаю, что это пока лучший. Однако я не собираюсь отмечать это как решение, пока не узнаю наверняка, что нет стандартного способа написать собственный итератор (как раньше). Голосование в любом случае. - person John Cast; 07.05.2015

Мне кажется, что вы хотите создать <div> для каждого массива идентификаторов (поправьте меня, если я ошибаюсь). Вот как бы я это сделал, не нужно никакого пользовательского итератора:

Template.registerHelper('ids', function(arrayWithIds) {
    if (!arrayWithIds) return [];
    // do some sorting or whatever with arrayWithIds, for example:
    var arrayOfIds = _.map(arrayWithIds, function(obj) {
        return obj._id;
    });
    return arrayOfIds;
});

Затем в main.html:

{{#each ids someDataSetWithIds}}
    // `someDataSetWithIds` is the helper's parameter
    // `this` in each case is an ID
    <div id="wow-{{this}}"></div>
{{/each}}

Если ваш помощник возвращает объект, вместо этого вы должны использовать this._id в шаблоне. Я неправильно понял, чего вы пытаетесь достичь?

person pfkurtz    schedule 21.04.2015
comment
Я ценю ответ, однако это не касается того, о чем я спрашиваю. Я уже могу создать эти div (по одному на идентификатор), как вы делаете в своем ответе. Проблема, которую я пытаюсь решить, заключается в том, что (насколько мне известно) пробелы не гарантируют, что #each всегда будет синхронным (даже при использовании его текущей реализации). Гарантированная последовательная итерация очень важна для моего приложения, поэтому я пытаюсь написать последовательный итератор, который заменит стандартный итератор #each, который можно найти в пробелах. - person John Cast; 23.04.2015
comment
Даже если моя причина создания этого итератора кажется параноидальной, не стесняйтесь подходить к моему вопросу с точки зрения того, как вообще создать/воссоздать итератор пробелов {{#each}} - person John Cast; 23.04.2015