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 + '"]').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) ->
if !_.isArray(name)
name = [name]

View file

@ -220,21 +220,36 @@ class App.Utils
changes
@_formDiffNormalizer: (data) ->
return undefined if data is undefined
return if !@_formDiffNormalizerCheckConstructor( data )
if _.isArray( data )
for i in [0...data.length]
data[i] = @_formDiffNormalizer( data[i] )
if @_formDiffNormalizerCheckConstructor( data[i] )
data[i] = @_formDiffNormalizer( data[i] )
else
data[i] = undefined
else if _.isObject( data )
for key, value of data
if _.isArray( data[key] )
@_formDiffNormalizer( data[key] )
else if _.isObject( data[key] )
@_formDiffNormalizer( data[key] )
else
else if @_formDiffNormalizerCheckConstructor( data[key] )
data[key] = @_formDiffNormalizerItem( key, data[key] )
else
@_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) ->

View file

@ -73,11 +73,49 @@ function difference(object1, object2) {
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) {
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
var types = [ Number, String, Boolean ],
var types = [ Number, String, Boolean ],
result;
// normalizing primitives if someone did new String('aaa'), or new Number('444');
@ -90,13 +128,13 @@ function clone(item) {
if (typeof result == "undefined") {
if (Object.prototype.toString.call( item ) === "[object Array]") {
result = [];
item.forEach(function(child, index, array) {
item.forEach(function(child, index, array) {
result[index] = clone( child );
});
} else if (typeof item == "object") {
// testing that this is DOM
if (item.nodeType && typeof item.cloneNode == "function") {
var result = item.cloneNode( true );
var result = item.cloneNode( true );
} else if (!item.prototype) { // check that this is a literal
if (item instanceof Date) {
result = new Date(item);
@ -121,6 +159,7 @@ function clone(item) {
result = item;
}
}
return result;
}

View file

@ -441,6 +441,7 @@ test( "clone", function() {
key2: '1234'
},
[1,2,4,5,6],
'some string äöü',
{
key1: 123,
key2: null,
@ -481,6 +482,22 @@ test( "clone", function() {
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

View file

@ -201,8 +201,8 @@ test( "date validation check", function() {
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').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(), '', '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
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' );
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' );
});
}