Added support for iterable objects in {{#each}} helper (#1557)
* Added support for iterable object in {{#each}} helper
Currently {{#each}} helper supports either arrays, or objects,
however nowadays you can define custom iterable objects by overriding
a special method called Symbol.iterator, which results in empty result
being rendered.
* improved a test for iterables in {{#each}} returning empty result
* #each helper: using ES5 instead of generator functions in tests
* #each helper: using ES5 in the helper itself
This commit is contained in:
@@ -49,6 +49,16 @@ export default function(instance) {
|
|||||||
execIteration(i, i, i === context.length - 1);
|
execIteration(i, i, i === context.length - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (global.Symbol && context[global.Symbol.iterator]) {
|
||||||
|
const newContext = [];
|
||||||
|
const iterator = context[global.Symbol.iterator]();
|
||||||
|
for (let it = iterator.next(); !it.done; it = iterator.next()) {
|
||||||
|
newContext.push(it.value);
|
||||||
|
}
|
||||||
|
context = newContext;
|
||||||
|
for (let j = context.length; i < j; i++) {
|
||||||
|
execIteration(i, i, i === context.length - 1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let priorKey;
|
let priorKey;
|
||||||
|
|
||||||
|
|||||||
@@ -254,6 +254,37 @@ describe('builtin helpers', function() {
|
|||||||
template({});
|
template({});
|
||||||
}, handlebarsEnv.Exception, 'Must pass iterator to #each');
|
}, handlebarsEnv.Exception, 'Must pass iterator to #each');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (global.Symbol && global.Symbol.iterator) {
|
||||||
|
it('each on iterable', function() {
|
||||||
|
function Iterator(arr) {
|
||||||
|
this.arr = arr;
|
||||||
|
this.index = 0;
|
||||||
|
}
|
||||||
|
Iterator.prototype.next = function() {
|
||||||
|
var value = this.arr[this.index];
|
||||||
|
var done = this.index === this.arr.length;
|
||||||
|
if (!done) {
|
||||||
|
this.index++;
|
||||||
|
}
|
||||||
|
return { value: value, done: done };
|
||||||
|
};
|
||||||
|
function Iterable(arr) {
|
||||||
|
this.arr = arr;
|
||||||
|
}
|
||||||
|
Iterable.prototype[global.Symbol.iterator] = function() {
|
||||||
|
return new Iterator(this.arr);
|
||||||
|
};
|
||||||
|
var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
|
||||||
|
var goodbyes = new Iterable([{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}]);
|
||||||
|
var goodbyesEmpty = new Iterable([]);
|
||||||
|
var hash = {goodbyes: goodbyes, world: 'world'};
|
||||||
|
shouldCompileTo(string, hash, 'goodbye! Goodbye! GOODBYE! cruel world!',
|
||||||
|
'each with array argument iterates over the contents when not empty');
|
||||||
|
shouldCompileTo(string, {goodbyes: goodbyesEmpty, world: 'world'}, 'cruel world!',
|
||||||
|
'each with array argument ignores the contents when empty');
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#log', function() {
|
describe('#log', function() {
|
||||||
|
|||||||
Reference in New Issue
Block a user