fix(select): use $viewValue instead of $modelValue

Closes #8929
This commit is contained in:
Shahar Talmi
2014-09-04 23:07:39 +03:00
committed by Jeff Cross
parent 0656484d3e
commit f7174169f4
2 changed files with 134 additions and 10 deletions

View File

@@ -436,16 +436,16 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
function getSelectedSet() {
var selectedSet = false;
if (multiple) {
var modelValue = ctrl.$modelValue;
if (trackFn && isArray(modelValue)) {
var viewValue = ctrl.$viewValue;
if (trackFn && isArray(viewValue)) {
selectedSet = new HashMap([]);
var locals = {};
for (var trackIndex = 0; trackIndex < modelValue.length; trackIndex++) {
locals[valueName] = modelValue[trackIndex];
selectedSet.put(trackFn(scope, locals), modelValue[trackIndex]);
for (var trackIndex = 0; trackIndex < viewValue.length; trackIndex++) {
locals[valueName] = viewValue[trackIndex];
selectedSet.put(trackFn(scope, locals), viewValue[trackIndex]);
}
} else {
selectedSet = new HashMap(modelValue);
selectedSet = new HashMap(viewValue);
}
}
return selectedSet;
@@ -470,7 +470,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
optionGroup,
option,
existingParent, existingOptions, existingOption,
modelValue = ctrl.$modelValue,
viewValue = ctrl.$viewValue,
values = valuesFn(scope) || [],
keys = keyName ? sortedKeys(values) : values,
key,
@@ -508,10 +508,10 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
} else {
if (trackFn) {
var modelCast = {};
modelCast[valueName] = modelValue;
modelCast[valueName] = viewValue;
selected = trackFn(scope, modelCast) === trackFn(scope, locals);
} else {
selected = modelValue === valueFn(scope, locals);
selected = viewValue === valueFn(scope, locals);
}
selectedSet = selectedSet || selected; // see if at least one item is selected
}
@@ -527,7 +527,7 @@ var selectDirective = ['$compile', '$parse', function($compile, $parse) {
});
}
if (!multiple) {
if (nullOption || modelValue === null) {
if (nullOption || viewValue === null) {
// insert null option if we have a placeholder, or the model is null
optionGroups[''].unshift({id:'', label:'', selected:!selectedSet});
} else if (!selectedSet) {

View File

@@ -1550,6 +1550,130 @@ describe('select', function() {
expect(scope.value).toBe(false);
});
});
describe('ngModelCtrl', function() {
it('should prefix the model value with the word "the" using $parsers', function() {
createSelect({
'name': 'select',
'ng-model': 'value',
'ng-options': 'item for item in [\'first\', \'second\', \'third\', \'fourth\']',
});
scope.form.select.$parsers.push(function(value) {
return 'the ' + value;
});
element.val('2');
browserTrigger(element, 'change');
expect(scope.value).toBe('the third');
expect(element.val()).toBe('2');
});
it('should prefix the view value with the word "the" using $formatters', function() {
createSelect({
'name': 'select',
'ng-model': 'value',
'ng-options': 'item for item in [\'the first\', \'the second\', \'the third\', \'the fourth\']',
});
scope.form.select.$formatters.push(function(value) {
return 'the ' + value;
});
scope.$apply(function() {
scope.value = 'third';
});
expect(element.val()).toBe('2');
});
it('should fail validation when $validators fail', function() {
createSelect({
'name': 'select',
'ng-model': 'value',
'ng-options': 'item for item in [\'first\', \'second\', \'third\', \'fourth\']',
});
scope.form.select.$validators.fail = function() {
return false;
};
element.val('2');
browserTrigger(element, 'change');
expect(element).toBeInvalid();
expect(scope.value).toBeUndefined();
expect(element.val()).toBe('2');
});
it('should pass validation when $validators pass', function() {
createSelect({
'name': 'select',
'ng-model': 'value',
'ng-options': 'item for item in [\'first\', \'second\', \'third\', \'fourth\']',
});
scope.form.select.$validators.pass = function() {
return true;
};
element.val('2');
browserTrigger(element, 'change');
expect(element).toBeValid();
expect(scope.value).toBe('third');
expect(element.val()).toBe('2');
});
it('should fail validation when $asyncValidators fail', inject(function($q, $rootScope) {
var defer;
createSelect({
'name': 'select',
'ng-model': 'value',
'ng-options': 'item for item in [\'first\', \'second\', \'third\', \'fourth\']',
});
scope.form.select.$asyncValidators.async = function() {
defer = $q.defer();
return defer.promise;
};
element.val('2');
browserTrigger(element, 'change');
expect(scope.form.select.$pending).toBeDefined();
expect(scope.value).toBeUndefined();
expect(element.val()).toBe('2');
defer.reject();
$rootScope.$digest();
expect(scope.form.select.$pending).toBeUndefined();
expect(scope.value).toBeUndefined();
expect(element.val()).toBe('2');
}));
it('should pass validation when $asyncValidators pass', inject(function($q, $rootScope) {
var defer;
createSelect({
'name': 'select',
'ng-model': 'value',
'ng-options': 'item for item in [\'first\', \'second\', \'third\', \'fourth\']',
});
scope.form.select.$asyncValidators.async = function() {
defer = $q.defer();
return defer.promise;
};
element.val('2');
browserTrigger(element, 'change');
expect(scope.form.select.$pending).toBeDefined();
expect(scope.value).toBeUndefined();
expect(element.val()).toBe('2');
defer.resolve();
$rootScope.$digest();
expect(scope.form.select.$pending).toBeUndefined();
expect(scope.value).toBe('third');
expect(element.val()).toBe('2');
}));
});
});