Skip to content

Commit ac439cb

Browse files
authored
Merge pull request #895 from mnzaki/development
Fix array item deletion issue
2 parents 7c9fff5 + a4f0ea8 commit ac439cb

File tree

3 files changed

+72
-37
lines changed

3 files changed

+72
-37
lines changed

src/directives/sf-array.directive.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,6 @@ export default function(sfSelect, sfPath, schemaForm) {
186186
model.splice(index, 1);
187187
}
188188

189-
if(item.$$hashKey) {
190-
scope.destroyed = item.$$hashKey;
191-
}
192-
193189
return model;
194190
};
195191

src/directives/sf-array.directive.spec.js

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,14 @@ describe('sf-array.directive.js', function() {
2424
"type": "array",
2525
"description": "foobar",
2626
"items": {
27-
"title": "Name",
28-
"type": "string",
29-
"default": 6,
27+
"type": "object",
28+
"properties": {
29+
"name": {
30+
"title": "Name",
31+
"type": "string",
32+
"default": 6,
33+
},
34+
},
3035
},
3136
},
3237
},
@@ -65,4 +70,34 @@ describe('sf-array.directive.js', function() {
6570
// tmpl.$valid.should.be.true;
6671
});
6772
});
73+
74+
it('should not delete innocent items on delete', function(done) {
75+
tmpl = angular.element('<form name="testform" sf-schema="schema" sf-form="form" sf-model="model" json="{{model | json}}"></form>');
76+
77+
inject(function($compile, $rootScope) {
78+
var scope = $rootScope.$new();
79+
scope.model = { names: [{ name: "0"}, {name: "1"}, {name: "2"}, {name: "3"}]};
80+
81+
scope.schema = exampleSchema;
82+
83+
scope.form = [ "*" ];
84+
85+
$compile(tmpl)(scope);
86+
runSync(scope, tmpl);
87+
88+
tmpl.find('div.help-block').text().should.equal('foobar');
89+
90+
var close = tmpl.find('button.close');
91+
close.eq(1).click();
92+
93+
$rootScope.$apply();
94+
95+
setTimeout(function() {
96+
scope.model.names[0].name.should.equal("0");
97+
scope.model.names[1].name.should.equal("2");
98+
scope.model.names[2].name.should.equal("3");
99+
done();
100+
}, 0)
101+
});
102+
});
68103
});

src/directives/sf-field.directive.js

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -308,44 +308,48 @@ export default function($parse, $compile, $interpolate, sfErrorMessage, sfPath,
308308

309309
// If the entire schema form is destroyed we don't touch the model
310310
if (!scope.externalDestructionInProgress) {
311-
let destroyStrategy = form.destroyStrategy ||
311+
var destroyStrategy = form.destroyStrategy ||
312312
(scope.options && scope.options.destroyStrategy) || 'remove';
313313
// No key no model, and we might have strategy 'retain'
314314
if (key && destroyStrategy !== 'retain') {
315-
// Get the object that has the property we wan't to clear.
316-
let obj = scope.model;
317-
if (key.length > 1) {
318-
obj = sfSelect(key.slice(0, key.length - 1), obj);
319-
}
320-
321-
if(obj && scope.destroyed && obj.$$hashKey && obj.$$hashKey !== scope.destroyed) {
322-
return;
323-
}
324-
325-
// We can get undefined here if the form hasn't been filled out entirely
326-
if (obj === undefined) {
327-
return;
328-
}
329315

330316
// Type can also be a list in JSON Schema
331-
let type = (form.schema && form.schema.type) || '';
317+
var type = (form.schema && form.schema.type) || '';
332318

333319
// Empty means '',{} and [] for appropriate types and undefined for the rest
334-
// console.log('destroy', destroyStrategy, key, type, obj);
335-
if (destroyStrategy === 'empty' && type.indexOf('string') !== -1) {
336-
obj[key.slice(-1)] = '';
337-
}
338-
else if (destroyStrategy === 'empty' && type.indexOf('object') !== -1) {
339-
obj[key.slice(-1)] = {};
340-
}
341-
else if (destroyStrategy === 'empty' && type.indexOf('array') !== -1) {
342-
obj[key.slice(-1)] = [];
343-
}
344-
else if (destroyStrategy === 'null') {
345-
obj[key.slice(-1)] = null;
320+
let value;
321+
if (destroyStrategy === 'empty') {
322+
value = type.indexOf('string') !== -1 ? '' :
323+
type.indexOf('object') !== -1 ? {} :
324+
type.indexOf('array') !== -1 ? [] : undefined;
325+
} else if (destroyStrategy === 'null') {
326+
value = null;
346327
}
347-
else {
348-
delete obj[key.slice(-1)];
328+
329+
if (value !== undefined) {
330+
sfSelect(key, scope.model, value);
331+
} else {
332+
// Get the object parent object
333+
let obj = scope.model;
334+
if (key.length > 1) {
335+
obj = sfSelect(key.slice(0, key.length - 1), obj)
336+
}
337+
338+
// parent can be undefined if the form hasn't been filled out
339+
// entirely
340+
if (obj === undefined) {
341+
return;
342+
}
343+
344+
// if parent is an array, then we have already been removed.
345+
// set flag to all children (who are about to recieve a $destroy
346+
// event as well) that we have already been destroyed
347+
if (angular.isArray(obj)) {
348+
scope.externalDestructionInProgress = true;
349+
return;
350+
}
351+
352+
delete obj[key[key.length-1]];
349353
}
350354
}
351355
}

0 commit comments

Comments
 (0)