mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-16 23:30:23 +00:00
fix($parse): unwrap promise when setting a field
This fixes an inconsistency where you can't call the setter function when the expression resolves to a top level field name on a promise. Setting a field on an unresolved promise will throw an exception. (This shouldn't really happen in your template/js code and points to a programming error.) Closes #1827
This commit is contained in:
parent
0bbd20f255
commit
61906d3517
2 changed files with 91 additions and 0 deletions
|
|
@ -766,6 +766,17 @@ function setter(obj, path, setValue, fullExp) {
|
|||
obj[key] = propertyObj;
|
||||
}
|
||||
obj = propertyObj;
|
||||
if (obj.then) {
|
||||
if (!("$$v" in obj)) {
|
||||
(function(promise) {
|
||||
promise.then(function(val) { promise.$$v = val; }); }
|
||||
)(obj);
|
||||
}
|
||||
if (obj.$$v === undefined) {
|
||||
obj.$$v = {};
|
||||
}
|
||||
obj = obj.$$v;
|
||||
}
|
||||
}
|
||||
key = ensureSafeMemberName(element.shift(), fullExp);
|
||||
obj[key] = setValue;
|
||||
|
|
|
|||
|
|
@ -845,6 +845,86 @@ describe('parser', function() {
|
|||
scope.$digest();
|
||||
expect(scope.$eval('greeting')).toBe(undefined);
|
||||
});
|
||||
|
||||
|
||||
describe('assignment into promises', function() {
|
||||
// This behavior is analogous to assignments to non-promise values
|
||||
// that are lazily set on the scope.
|
||||
it('should evaluate a resolved object promise and set its value', inject(function($parse) {
|
||||
scope.person = promise;
|
||||
deferred.resolve({'name': 'Bill Gates'});
|
||||
|
||||
var getter = $parse('person.name');
|
||||
expect(getter(scope)).toBe(undefined);
|
||||
|
||||
scope.$digest();
|
||||
expect(getter(scope)).toBe('Bill Gates');
|
||||
getter.assign(scope, 'Warren Buffet');
|
||||
expect(getter(scope)).toBe('Warren Buffet');
|
||||
}));
|
||||
|
||||
|
||||
it('should evaluate a resolved primitive type promise and set its value', inject(function($parse) {
|
||||
scope.greeting = promise;
|
||||
deferred.resolve('Salut!');
|
||||
|
||||
var getter = $parse('greeting');
|
||||
expect(getter(scope)).toBe(undefined);
|
||||
|
||||
scope.$digest();
|
||||
expect(getter(scope)).toBe('Salut!');
|
||||
|
||||
getter.assign(scope, 'Bonjour');
|
||||
expect(getter(scope)).toBe('Bonjour');
|
||||
}));
|
||||
|
||||
|
||||
it('should evaluate an unresolved promise and set and remember its value', inject(function($parse) {
|
||||
scope.person = promise;
|
||||
|
||||
var getter = $parse('person.name');
|
||||
expect(getter(scope)).toBe(undefined);
|
||||
|
||||
scope.$digest();
|
||||
expect(getter(scope)).toBe(undefined);
|
||||
|
||||
getter.assign(scope, 'Bonjour');
|
||||
scope.$digest();
|
||||
|
||||
expect(getter(scope)).toBe('Bonjour');
|
||||
|
||||
var c1Getter = $parse('person.A.B.C1');
|
||||
scope.$digest();
|
||||
expect(c1Getter(scope)).toBe(undefined);
|
||||
c1Getter.assign(scope, 'c1_value');
|
||||
scope.$digest();
|
||||
expect(c1Getter(scope)).toBe('c1_value');
|
||||
|
||||
// Set another property on the person.A.B
|
||||
var c2Getter = $parse('person.A.B.C2');
|
||||
scope.$digest();
|
||||
expect(c2Getter(scope)).toBe(undefined);
|
||||
c2Getter.assign(scope, 'c2_value');
|
||||
scope.$digest();
|
||||
expect(c2Getter(scope)).toBe('c2_value');
|
||||
|
||||
// c1 should be unchanged.
|
||||
expect($parse('person.A')(scope)).toEqual(
|
||||
{B: {C1: 'c1_value', C2: 'c2_value'}});
|
||||
}));
|
||||
|
||||
|
||||
it('should evaluate a resolved promise and overwrite the previous set value in the absense of the getter',
|
||||
inject(function($parse) {
|
||||
scope.person = promise;
|
||||
var c1Getter = $parse('person.A.B.C1');
|
||||
c1Getter.assign(scope, 'c1_value');
|
||||
// resolving the promise should update the tree.
|
||||
deferred.resolve({A: {B: {C1: 'resolved_c1'}}});
|
||||
scope.$digest();
|
||||
expect(c1Getter(scope)).toEqual('resolved_c1');
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('dereferencing', function() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue