From 3295bc92c5c373da360583ace8011de44c77ac02 Mon Sep 17 00:00:00 2001 From: user378230 Date: Sat, 5 Mar 2016 23:04:05 +0000 Subject: [PATCH 1/2] fix(parser) allow track by without filter Previously the parser always attempted to extract a filter from the repeat expression, regardless of whether it was present or not. This resulted in the track by part of the expression being interpreted as a filter. This commit changes the parser regex to capture the entire object source, including its filters, before matching any track by expression. The filters are then extracted separately from the source as this step is only required when using an object as a source. Fixes #1233 --- src/uisRepeatParserService.js | 38 ++++++++++++++++++++++------------- test/select.spec.js | 26 ++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/uisRepeatParserService.js b/src/uisRepeatParserService.js index 5ee44bc72..1b5ce822b 100644 --- a/src/uisRepeatParserService.js +++ b/src/uisRepeatParserService.js @@ -22,38 +22,48 @@ uis.service('uisRepeatParser', ['uiSelectMinErr','$parse', function(uiSelectMinE var match; - var isObjectCollection = /\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)/.test(expression); + //var isObjectCollection = /\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)/.test(expression); // If an array is used as collection // if (isObjectCollection){ - //00000000000000000000000000000111111111000000000000000222222222222220033333333333333333333330000444444444444444444000000000000000556666660000077777777777755000000000000000000000088888880000000 - match = expression.match(/^\s*(?:([\s\S]+?)\s+as\s+)?(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(([\w\.]+)?\s*(|\s*[\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/); + // 000000000000000000000000000000111111111000000000000000222222222222220033333333333333333333330000444444444444444444000000000000000055555555555000000000000000000000066666666600000000 + match = expression.match(/^\s*(?:([\s\S]+?)\s+as\s+)?(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(\s*[\s\S]+?)?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/); // 1 Alias // 2 Item // 3 Key on (key,value) // 4 Value on (key,value) - // 5 Collection expresion (only used when using an array collection) - // 6 Object that will be converted to Array when using (key,value) syntax - // 7 Filters that will be applied to #6 when using (key,value) syntax - // 8 Track by + // 5 Source expression (including filters) + // 6 Track by if (!match) { throw uiSelectMinErr('iexp', "Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.", expression); } - if (!match[6] && isObjectCollection) { - throw uiSelectMinErr('iexp', "Expected expression in form of '_item_ as (_key_, _item_) in _ObjCollection_ [ track by _id_]' but got '{0}'.", - expression); + + var source = match[5], + filters = ''; + + // When using (key,value) ui-select requires filters to be extracted, since the object + // is converted to an array for $select.items + // (in which case the filters need to be reapplied) + if (match[3]) { + // Remove any enclosing parenthesis + source = match[5].replace(/(^\()|(\)$)/g, ''); + // match all after | but not after || + var filterMatch = match[5].match(/^\s*(?:[\s\S]+?)(?:[^\|]|\|\|)+([\s\S]*)\s*$/); + if(filterMatch && filterMatch[1].trim()) { + filters = filterMatch[1]; + source = source.replace(filters, ''); + } } return { itemName: match[4] || match[2], // (lhs) Left-hand side, keyName: match[3], //for (key, value) syntax - source: $parse(!match[3] ? match[5] : match[6]), - sourceName: match[6], - filters: match[7], - trackByExp: match[8], + source: $parse(source), + filters: filters, + trackByExp: match[6], modelMapper: $parse(match[1] || match[4] || match[2]), repeatExpression: function (grouped) { var expression = this.itemName + ' in ' + (grouped ? '$group.items' : '$select.items'); diff --git a/test/select.spec.js b/test/select.spec.js index 7c4018638..97714af61 100644 --- a/test/select.spec.js +++ b/test/select.spec.js @@ -260,6 +260,32 @@ describe('ui-select tests', function() { }); + it('should parse simple property binding repeat syntax with a basic filter', function () { + + var locals = {}; + locals.people = [{ name: 'Wladimir' }, { name: 'Samantha' }]; + locals.person = locals.people[1]; + + var parserResult = uisRepeatParser.parse('person.name as person in people | filter: { name: \'Samantha\' }'); + expect(parserResult.itemName).toBe('person'); + expect(parserResult.modelMapper(locals)).toBe(locals.person.name); + expect(parserResult.source(locals)).toEqual([locals.person]); + + }); + + it('should parse simple property binding repeat syntax with track by', function () { + + var locals = {}; + locals.people = [{ name: 'Wladimir' }, { name: 'Samantha' }]; + locals.person = locals.people[0]; + + var parserResult = uisRepeatParser.parse('person.name as person in people track by person.name'); + expect(parserResult.itemName).toBe('person'); + expect(parserResult.modelMapper(locals)).toBe(locals.person.name); + expect(parserResult.source(locals)).toBe(locals.people); + + }); + it('should parse (key, value) repeat syntax', function() { var locals = {}; From 9af47d889de8b07a4ff9d5dafaf8d3774e7cc5af Mon Sep 17 00:00:00 2001 From: user378230 Date: Sun, 6 Mar 2016 11:01:54 +0000 Subject: [PATCH 2/2] chore(release): bump package version and update changelog --- CHANGELOG.md | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4d3226e6..358a6ee3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ + +## [0.14.9](https://github.com/angular-ui/ui-select/compare/v0.14.9...v0.14.9) (2016-03-06) + + + + ## [0.14.8](https://github.com/angular-ui/ui-select/compare/v0.14.8...v0.14.8) (2016-02-18) diff --git a/package.json b/package.json index 02c1ad4a5..9846ad083 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "url": "git://github.com/angular-ui/ui-select.git" }, "style": "dist/select.css", - "version": "0.14.9", + "version": "0.14.10", "devDependencies": { "bower": "~1.3", "conventional-changelog": "^0.5.3",