From dc9e84e99bfff859886276c462f6d8b9715fd936 Mon Sep 17 00:00:00 2001 From: Omer Ganim Date: Sun, 15 May 2016 16:36:53 +0300 Subject: [PATCH] add option for custom index variable in react templates (fixes #88) --- README.md | 3 ++- src/reactTemplates.js | 11 ++++++++--- test/data/repeat-with-index.rt | 3 +++ test/data/repeat-with-index.rt.js | 16 ++++++++++++++++ test/src/rt.valid.spec.js | 2 +- 5 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 test/data/repeat-with-index.rt create mode 100644 test/data/repeat-with-index.rt.js diff --git a/README.md b/README.md index 00296ca..48055cd 100644 --- a/README.md +++ b/README.md @@ -126,8 +126,9 @@ define([ ``` ## rt-repeat -Repeats a DOM node with its subtree for each item in an array. The syntax is `rt-repeat="itemVar in arrayExpr"`, where the element, `itemVar`, will be available in JavaScript context, +Repeats a DOM node with its subtree for each item in an array. The syntax is `rt-repeat="itemVar, indexVar in arrayExpr"`, where the element, `itemVar`, will be available in JavaScript context, and an `itemVarIndex` will be created to represent the index of the item. By using this naming scheme, repeated expressions have access to all levels of nesting. +It is also possible to declare a custom index variable using the syntax `rt-repeat="itemVar, indexVar in arrayExpr"`, in which case the index variable will be `indexVar`. ###### Sample: ```html diff --git a/src/reactTemplates.js b/src/reactTemplates.js index c2bfd2f..a2e1a27 100644 --- a/src/reactTemplates.js +++ b/src/reactTemplates.js @@ -316,11 +316,16 @@ function convertHtmlToReact(node, context) { if (arr.length !== 2) { throw RTCodeError.build(context, node, `rt-repeat invalid 'in' expression '${node.attribs[repeatAttr]}'`); } - data.item = arr[0].trim(); + const repeaterParams = arr[0].split(',').map(s => s.trim()); + data.item = repeaterParams[0]; + data.index = repeaterParams[1] || `${data.item}Index`; data.collection = arr[1].trim(); - validateJS(data.item, node, context); + const bindParams = [data.item, data.index]; + _.forEach(bindParams, param => { + validateJS(param, node, context); + }); validateJS(`(${data.collection})`, node, context); - [data.item, `${data.item}Index`].forEach(param => { + _.forEach(bindParams, param => { if (!_.includes(context.boundParams, param)) { context.boundParams.push(param); } diff --git a/test/data/repeat-with-index.rt b/test/data/repeat-with-index.rt new file mode 100644 index 0000000..fbc44ea --- /dev/null +++ b/test/data/repeat-with-index.rt @@ -0,0 +1,3 @@ + diff --git a/test/data/repeat-with-index.rt.js b/test/data/repeat-with-index.rt.js new file mode 100644 index 0000000..a18eb2e --- /dev/null +++ b/test/data/repeat-with-index.rt.js @@ -0,0 +1,16 @@ +define([ + 'react', + 'lodash' +], function (React, _) { + 'use strict'; + function repeatItem1(item, customIndex) { + return React.createElement('li', {}, item, ' is number ', customIndex); + } + return function () { + return React.createElement.apply(this, [ + 'ul', + {}, + _.map(this.props.collection, repeatItem1.bind(this, customIndex)) + ]); + }; +}); diff --git a/test/src/rt.valid.spec.js b/test/src/rt.valid.spec.js index 86c3bf5..165bfd5 100644 --- a/test/src/rt.valid.spec.js +++ b/test/src/rt.valid.spec.js @@ -29,7 +29,7 @@ module.exports = { }); test('conversion test', t => { - const files = ['div.rt', 'test.rt', 'repeat.rt', 'inputs.rt', 'virtual.rt', 'stateless.rt']; + const files = ['div.rt', 'test.rt', 'repeat.rt', 'repeat-with-index.rt', 'inputs.rt', 'virtual.rt', 'stateless.rt']; testFiles(t, files); });