Skip to content

Commit

Permalink
feat(plugin.nested_dirty): specifies how changing a nested object pro…
Browse files Browse the repository at this point in the history
…perty

to another type affects changed property list.
  • Loading branch information
iobaixas authored and Chris Hanson committed Dec 11, 2014
1 parent 94bf937 commit 2a29577
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 14 deletions.
25 changes: 12 additions & 13 deletions src/plugins/nested-dirty.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,28 @@ angular.module('restmod').factory('NestedDirtyModel', ['restmod', function(restm
function navigate(_target, _keys) {
var key, i = 0;
while((key = _keys[i++])) {
if(_target && _target.hasOwnProperty(key)) _target = _target[key];
if(_target) {
_target = _target.hasOwnProperty(key) ? _target[key] : null;
}
}
return _target;
}

function hasValueChanged(_model, _original, _keys, _comparator) {
var isDirty = false,
prop = _keys.pop();
var prop = _keys.pop();

_model = navigate(_model, _keys);
_original = navigate(_original, _keys);

if(_original.hasOwnProperty(prop)) {
if(angular.isObject(_original) && angular.isObject(_model) && _original.hasOwnProperty(prop)) {
if(typeof _comparator === 'function') {
isDirty = !!_comparator(_model[prop], _original[prop]);
return !!_comparator(_model[prop], _original[prop]);
} else {
isDirty = !angular.equals(_model[prop], _original[prop]);
return !angular.equals(_model[prop], _original[prop]);
}
}

return isDirty;
return false;
}

function findChangedValues(_model, _original, _keys, _comparator) {
Expand All @@ -61,10 +62,8 @@ angular.module('restmod').factory('NestedDirtyModel', ['restmod', function(restm
if(isPlainObject(_original[key]) && isPlainObject(_model[key])) {
childChanges = findChangedValues(_model[key], _original[key], _keys.concat([key]), _comparator);
changes.push.apply(changes, childChanges);
} else {
if(hasValueChanged(_model, _original, [key], _comparator)) {
changes.push(_keys.concat([key]));
}
} else if(hasValueChanged(_model, _original, [key], _comparator)) {
changes.push(_keys.concat([key]));
}
}
}
Expand All @@ -73,7 +72,7 @@ angular.module('restmod').factory('NestedDirtyModel', ['restmod', function(restm
return changes;
}

function changesToStrings(_changes) {
function changesAsStrings(_changes) {
for(var i = 0, l = _changes.length; i < l; i++) {
_changes[i] = _changes[i].join('.');
}
Expand Down Expand Up @@ -123,7 +122,7 @@ angular.module('restmod').factory('NestedDirtyModel', ['restmod', function(restm
return hasValueChanged(this, original, _prop.split('.'), _comparator);
} else {
if(angular.isFunction(_prop)) _comparator = _prop;
return changesToStrings(findChangedValues(this, original, [], _comparator));
return changesAsStrings(findChangedValues(this, original, [], _comparator));
}
})
/**
Expand Down
15 changes: 14 additions & 1 deletion test/plugins/nested-dirty-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,24 @@ describe('Plugin: Nested Dirty Model', function() {
expect(bike.$dirty()).toContain('stickers');
});

it('should detect missing objects', function() {
it('should detect missing object properties', function() {
bike.customisations = null;
expect(bike.$dirty()).toContain('customisations');
});

it('should detect properties that change type from object', function() {
bike.customisations = 0;
expect(bike.$dirty()).toContain('customisations');
});

it('should not consider changes on child properties when parent object changes', function() {
bike.customisations = null;
expect(bike.$dirty('customisations.wheels')).toBeFalsy();

bike.model = { name: 'Meta', version: '2' };
expect(bike.$dirty('model.name')).toBeFalsy();
});

it('should compare with comparator function', function() {
bike.customisations.wheels = 3;
expect(bike.$dirty('customisations.wheels', function (newVal, oldVal) {
Expand Down

0 comments on commit 2a29577

Please sign in to comment.