Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e7cda24

Browse files
committedSep 30, 2015
wip: yet another way
- noop add/removeOption in selectCtrl. Prevents options from being added before by directives that compile before select - add add/remove in select preLink - noop add/remove again in ngOptions. Prevents options from being added by directive that run postLink before ngOptions
1 parent ca51125 commit e7cda24

File tree

3 files changed

+61
-44
lines changed

3 files changed

+61
-44
lines changed
 

‎src/ng/directive/ngOptions.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,8 @@ var ngOptionsDirective = ['$compile', '$parse', function($compile, $parse) {
729729
require: ['select', 'ngModel'],
730730
link: {
731731
pre: function ngOptionsPreLink(scope, selectElement, attr, ctrls) {
732-
ctrls[0].ngModelCtrl = null;
732+
ctrls[0].addOption = noop;
733+
ctrls[0].removeOption = noop;
733734
},
734735
post: ngOptionsPostLink
735736
}

‎src/ng/directive/select.js

+34-30
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ var SelectController =
1616
var self = this,
1717
optionsMap = new HashMap();
1818

19+
self.optionsMap = optionsMap;
20+
1921
// If the ngModel doesn't get provided then provide a dummy noop version to prevent errors
2022
self.ngModelCtrl = noopNgModelController;
2123

@@ -68,31 +70,8 @@ var SelectController =
6870
}
6971
};
7072

71-
72-
// Tell the select control that an option, with the given value, has been added
73-
self.addOption = function(value, element) {
74-
assertNotHasOwnProperty(value, '"option value"');
75-
if (value === '') {
76-
self.emptyOption = element;
77-
}
78-
var count = optionsMap.get(value) || 0;
79-
optionsMap.put(value, count + 1);
80-
};
81-
82-
// Tell the select control that an option, with the given value, has been removed
83-
self.removeOption = function(value) {
84-
var count = optionsMap.get(value);
85-
if (count) {
86-
if (count === 1) {
87-
optionsMap.remove(value);
88-
if (value === '') {
89-
self.emptyOption = undefined;
90-
}
91-
} else {
92-
optionsMap.put(value, count - 1);
93-
}
94-
}
95-
};
73+
self.addOption = noop;
74+
self.removeOption = noop;
9675

9776
// Check whether the select control has an option matching the given value
9877
self.hasOption = function(value) {
@@ -324,6 +303,36 @@ var selectDirective = function() {
324303

325304
selectCtrl.ngModelCtrl = ngModelCtrl;
326305

306+
// Tell the select control that an option, with the given value, has been added
307+
selectCtrl.addOption = function(value, element) {
308+
assertNotHasOwnProperty(value, '"option value"');
309+
if (value === '') {
310+
selectCtrl.emptyOption = element;
311+
}
312+
var count = selectCtrl.optionsMap.get(value) || 0;
313+
selectCtrl.optionsMap.put(value, count + 1);
314+
315+
element.on('$destroy', function() {
316+
selectCtrl.removeOption(value);
317+
selectCtrl.ngModelCtrl.$render();
318+
});
319+
};
320+
321+
// Tell the select control that an option, with the given value, has been removed
322+
selectCtrl.removeOption = function(value) {
323+
var count = selectCtrl.optionsMap.get(value);
324+
if (count) {
325+
if (count === 1) {
326+
selectCtrl.optionsMap.remove(value);
327+
if (value === '') {
328+
selectCtrl.emptyOption = undefined;
329+
}
330+
} else {
331+
selectCtrl.optionsMap.put(value, count - 1);
332+
}
333+
}
334+
};
335+
327336
// We delegate rendering to the `writeValue` method, which can be changed
328337
// if the select can have multiple selected values or if the options are being
329338
// generated by `ngOptions`
@@ -460,11 +469,6 @@ var optionDirective = ['$interpolate', function($interpolate) {
460469
// The value attribute is static
461470
addOption(attr.value);
462471
}
463-
464-
element.on('$destroy', function() {
465-
selectCtrl.removeOption(attr.value);
466-
selectCtrl.ngModelCtrl.$render();
467-
});
468472
}
469473
};
470474
}

‎test/ng/directive/ngOptionsSpec.js

+25-13
Original file line numberDiff line numberDiff line change
@@ -125,12 +125,15 @@ describe('ngOptions', function() {
125125

126126
.directive('oCompileContents', function() {
127127
return {
128-
link: function(scope, element) {
129-
linkLog.push('linkCompileContents');
130-
$compile(element.contents())(scope);
128+
priority: 2,
129+
link: {
130+
pre: function(scope, element) {
131+
linkLog.push('linkCompileContents');
132+
$compile(element.contents())(scope);
133+
}
131134
}
132135
};
133-
});
136+
});
134137

135138
$provide.decorator('ngOptionsDirective', function($delegate) {
136139

@@ -2170,29 +2173,38 @@ describe('ngOptions', function() {
21702173

21712174
it('should not throw when a directive compiles the blank option before ngOptions is linked', function() {
21722175
expect(function() {
2173-
createSelect({
2174-
'o-compile-contents': '',
2175-
'name': 'select',
2176-
'ng-model': 'value',
2177-
'ng-options': 'item for item in items'
2176+
createSelect({
2177+
'o-compile-contents': '',
2178+
'name': 'select',
2179+
'ng-model': 'value',
2180+
'ng-options': 'item for item in items'
21782181
}, true);
21792182
}).not.toThrow();
21802183

21812184
expect(linkLog).toEqual(['linkCompileContents', 'linkNgOptions']);
2185+
2186+
var options = element.find('option');
2187+
expect(options.length).toBe(1);
2188+
expect(options.eq(0).val()).toBe('');
2189+
expect(options.eq(0).text()).toBe('blank');
21822190
});
21832191

21842192

21852193
it('should not throw with a directive that replaces', inject(function($templateCache, $httpBackend) {
2186-
$templateCache.put('select_template.html', '<select ng-options="option as option for option in selectable_options"> <option value="">This is a test</option> </select>');
2194+
$templateCache.put('select_template.html', '<select ng-options="option as option for option in selectable_options"> <option value="">--select--</option> </select>');
21872195

2188-
scope.options = ['a', 'b', 'c', 'd'];
2196+
scope.options = ['a', 'b', 'c'];
21892197

21902198
expect(function() {
2191-
var element = $compile('<custom-select ng-model="value" options="options"></custom-select>')(scope);
2199+
element = $compile('<custom-select ng-model="value" options="options"></custom-select>')(scope);
21922200
scope.$digest();
2193-
dealoc(element);
21942201
}).not.toThrow();
21952202

2203+
var options = element.find('option');
2204+
expect(options.length).toBe(4);
2205+
expect(options.eq(0).val()).toBe('');
2206+
expect(options.eq(0).text()).toBe('--select--');
2207+
dealoc(element);
21962208
}));
21972209

21982210
});

0 commit comments

Comments
 (0)
This repository has been archived.