Improved clone() - only clone data, no objects.

This commit is contained in:
Martin Edenhofer 2015-01-29 14:19:11 +01:00
parent fd022ee01c
commit 644cd811e7
6 changed files with 144 additions and 9 deletions

View file

@ -1998,6 +1998,11 @@ class App.ControllerForm extends App.Controller
el.find('[data-name="' + key + '"]').closest('.form-group').removeClass('hide') el.find('[data-name="' + key + '"]').closest('.form-group').removeClass('hide')
el.find('[data-name="' + key + '"]').removeClass('is-hidden') el.find('[data-name="' + key + '"]').removeClass('is-hidden')
# hide old validation states
if el
el.find('.has-error').removeClass('has-error')
el.find('.help-inline').html('')
_hide: (name, el = @el) -> _hide: (name, el = @el) ->
if !_.isArray(name) if !_.isArray(name)
name = [name] name = [name]

View file

@ -220,21 +220,36 @@ class App.Utils
changes changes
@_formDiffNormalizer: (data) -> @_formDiffNormalizer: (data) ->
return undefined if data is undefined
return if !@_formDiffNormalizerCheckConstructor( data )
if _.isArray( data ) if _.isArray( data )
for i in [0...data.length] for i in [0...data.length]
if @_formDiffNormalizerCheckConstructor( data[i] )
data[i] = @_formDiffNormalizer( data[i] ) data[i] = @_formDiffNormalizer( data[i] )
else
data[i] = undefined
else if _.isObject( data ) else if _.isObject( data )
for key, value of data for key, value of data
if _.isArray( data[key] ) if _.isArray( data[key] )
@_formDiffNormalizer( data[key] ) @_formDiffNormalizer( data[key] )
else if _.isObject( data[key] ) else if _.isObject( data[key] )
@_formDiffNormalizer( data[key] ) @_formDiffNormalizer( data[key] )
else else if @_formDiffNormalizerCheckConstructor( data[key] )
data[key] = @_formDiffNormalizerItem( key, data[key] ) data[key] = @_formDiffNormalizerItem( key, data[key] )
else else
@_formDiffNormalizerItem( '', data ) @_formDiffNormalizerItem( '', data )
@_formDiffNormalizerCheckConstructor: (data) ->
return true if !data
return true if !data.constructor
name = data.constructor.name
return true if !name
return true if name is 'Object'
return true if name is 'Array'
return true if name is 'String'
return true if name is 'Number'
false
@_formDiffNormalizerItem: (key, value) -> @_formDiffNormalizerItem: (key, value) ->

View file

@ -73,8 +73,46 @@ function difference(object1, object2) {
return changes; return changes;
} }
// taken from http://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript // clone, just data, no instances of objects
function clone(item) { function clone(item) {
if (!item) { return item; }
// ignore certain objects
var acceptedInstances = [ 'Object', 'Number', 'String', 'Boolean', 'Array' ];
if (item && item.constructor) {
if (!_.contains(acceptedInstances, item.constructor.name)) {
return;
}
}
var result;
// copy array
if ( _.isArray(item) ) {
result = [];
item.forEach(function(child, index, array) {
result[index] = clone( child );
});
}
// copy object
else if ( _.isObject(item) ) {
result = {};
for(var key in item) {
if (item.hasOwnProperty(key)) {
result[key] = clone(item[key])
}
}
}
// copy others
else {
result = item;
}
return result;
}
// taken from http://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript
function clone2(item) {
if (!item) { return item; } // null, undefined values check if (!item) { return item; } // null, undefined values check
var types = [ Number, String, Boolean ], var types = [ Number, String, Boolean ],
@ -121,6 +159,7 @@ function clone(item) {
result = item; result = item;
} }
} }
return result; return result;
} }

View file

@ -441,6 +441,7 @@ test( "clone", function() {
key2: '1234' key2: '1234'
}, },
[1,2,4,5,6], [1,2,4,5,6],
'some string äöü',
{ {
key1: 123, key1: 123,
key2: null, key2: null,
@ -481,6 +482,22 @@ test( "clone", function() {
deepEqual( item, test, 'clone' ); deepEqual( item, test, 'clone' );
}); });
// complex test
var source = [
{ name: 'some name' },
{ name: 'some name2' },
]
var reference = [
{ name: 'some name' },
{ name: 'some name2' },
]
var result = clone( source )
// modify source later, should not have any result
source[0].name = 'some new name'
deepEqual( result, reference, 'clone' );
}); });
// diff // diff

View file

@ -201,8 +201,8 @@ test( "date validation check", function() {
App.ControllerForm.validate( { errors: errors, form: el } ) App.ControllerForm.validate( { errors: errors, form: el } )
equal( el.find('[data-name="date1"]').closest('.form-group').hasClass('has-error'), true, 'check date1 has-error') equal( el.find('[data-name="date1"]').closest('.form-group').hasClass('has-error'), true, 'check date1 has-error')
equal( el.find('[data-name="date1"]').closest('.form-group').find('.help-inline').text(), '', 'check date1 error message') //equal( el.find('[data-name="date1"]').closest('.form-group').find('.help-inline').text(), '', 'check date1 error message')
//equal( el.find('[data-name="date1"]').closest('.form-group').find('.help-inline').text(), 'is required', 'check date1 error message') equal( el.find('[data-name="date1"]').closest('.form-group').find('.help-inline').text(), 'is required', 'check date1 error message')
// set new values // set new values
el.find('[name="{date}date1___day"]').val('1') el.find('[name="{date}date1___day"]').val('1')

View file

@ -877,6 +877,65 @@ test( "check form diff", function() {
deepEqual( result, diff, 'check form diff' ); deepEqual( result, diff, 'check form diff' );
dataNow = undefined
dataLast = undefined
diff = {}
result = App.Utils.formDiff( dataNow, dataLast )
deepEqual( result, diff, 'check form diff' );
dataNow = {}
dataLast = {"number":"10012","title":"some subject 123äöü","group_id":1,"owner_id":1,"customer_id":2,"state_id":3,"priority_id":2,"article":{"from":"Test Master Agent","to":"","cc":"","body":"dasdad","content_type":"text/html","ticket_id":12,"type_id":9,"sender_id":1,"internal":false,"form_id":"523405147"},"updated_at":"2015-01-29T09:22:23.000Z","pending_time":"2015-01-28T22:22:00.000Z","id":12}
diff = {}
result = App.Utils.formDiff( dataNow, dataLast )
deepEqual( result, diff, 'check form diff' );
// do not compare content of data instances/objects
no = function test_object() {
this.a = function() { return 123; }
this.b = function() { return '1234'; }
this.c = function() { return [123]; }
this.d = [1,2,3];
this.e = 'abc';
}
no1 = new no()
no2 = new no()
no3 = new no()
dataNow = {
number:'10013',
Article: [no1],
}
dataLast = {
number: "10012",
title: "some subject 123äöü",
Article: [ no2, no3 ],
}
diff = {
number:'10013',
}
result = App.Utils.formDiff( dataNow, dataLast )
deepEqual( result, diff, 'check form diff' );
dataNow = {
number:'10013',
Article: [no1,2],
}
dataLast = {
number: "10012",
title: "some subject 123äöü",
Article: [ no2, no3 ],
}
diff = {
number:'10013',
Article: ['2'],
}
result = App.Utils.formDiff( dataNow, dataLast )
deepEqual( result, diff, 'check form diff' );
}); });
} }