From c32a859bdb93699cc080f9affed4bcff63005a64 Mon Sep 17 00:00:00 2001 From: quazzie Date: Tue, 14 May 2013 19:56:11 +0100 Subject: feat(select): match options by expression other than object identity Extend ng-options with a new clause, "track by [trackByExpression]", which can be used when working with objects. The `trackByExpression` should uniquely identify select options objects. This solves the problem of previously having to match ng-options objects by identity. You can now write: `ng-options="obj as obj.name for obj in objects track by obj.id"` The "track by" expression will be used when checking for equality of objects. Examples: scope: { user: { name: 'Test user', favMovieStub: { id: 1, name: 'Starwars' } } movies: [{ id: 1, name: 'Starwars', rating: 5, ... }, { id: 13, ... }] } The select input will match user favMovieStub to the first movie in the movies array, and show "Star Wars" as the selected item. --- test/ng/directive/selectSpec.js | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/ng/directive/selectSpec.js b/test/ng/directive/selectSpec.js index 91d09893..0cb2a812 100644 --- a/test/ng/directive/selectSpec.js +++ b/test/ng/directive/selectSpec.js @@ -495,7 +495,7 @@ describe('select', function() { expect(function() { compile(''); }).toThrow("Expected ngOptions in form of '_select_ (as _label_)? for (_key_,)?_value_ in" + - " _collection_' but got 'i dont parse'."); + " _collection_ (track by _expr_)?' but got 'i dont parse'."); }); @@ -753,6 +753,37 @@ describe('select', function() { }); + it('should bind to scope value and track/identify objects', function() { + createSelect({ + 'ng-model': 'selected', + 'ng-options': 'item as item.name for item in values track by item.id' + }); + + scope.$apply(function() { + scope.values = [{id: 1, name: 'first'}, + {id: 2, name: 'second'}, + {id: 3, name: 'third'}, + {id: 4, name: 'forth'}]; + scope.selected = {id: 2}; + }); + + expect(element.val()).toEqual('2'); + + var first = jqLite(element.find('option')[0]); + expect(first.text()).toEqual('first'); + expect(first.attr('value')).toEqual('1'); + var forth = jqLite(element.find('option')[3]); + expect(forth.text()).toEqual('forth'); + expect(forth.attr('value')).toEqual('4'); + + scope.$apply(function() { + scope.selected = scope.values[3]; + }); + + expect(element.val()).toEqual('4'); + }); + + it('should bind to scope value through experession', function() { createSelect({ 'ng-model': 'selected', -- cgit v1.2.3