Skip to content

Commit 2488ba8

Browse files
committed
Reworked destroy srategy
Work in progress. Changed option to alway be a string and also stopped destruction on external event by a flag on scope.
1 parent 30069ff commit 2488ba8

File tree

3 files changed

+70
-24
lines changed

3 files changed

+70
-24
lines changed

docs/index.md

+17-8
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ General options most field types can handle:
636636
labelHtmlClass: "street" // CSS Class(es) to be added to the label of the field (or similar)
637637
copyValueTo: ["address.street"], // Copy values to these schema keys.
638638
condition: "person.age < 18" // Show or hide field depending on an angular expression
639-
destroyStrategy: null // One of null, empty string, undefined, or 'retain'. Changes model on $destroy event.
639+
destroyStrategy: "remove" // One of "null", "empty" , "remove", or 'retain'. Changes model on $destroy event. default is "remove".
640640
}
641641
```
642642
@@ -827,14 +827,23 @@ Note that arrays inside arrays won't work with conditions.
827827
828828
829829
### destroyStrategy
830-
By default, when a field is removed from the DOM and the $destroy event is broadcast, the schema-validate directive
831-
will update the model to set the field value to undefined. This can be overridden by setting the destroyStrategy
832-
on a field to one of null, empty string (""), undefined, or "retain". Any other value will be ignored and the default
833-
behavior will apply. The empty string option only applies to fields that have a type of string; using the empty string
834-
with other field types will just be set to the default destroyStrategy. If you'd like to set the destroyStrategy for
835-
an entire form, add it to the [globalOptions](#global-options)
830+
By default, when a field is removed from the DOM and the `$destroy` event is broadcast, this happens
831+
if you use the `condition` option, the schema-validate directive will update the model to set the
832+
field value to `undefined`. This can be overridden by setting the destroyStrategy on a field, or as a
833+
global option, to one of the strings `"null"`, `"empty"` , `"remove"`, or `"retain"`.
834+
835+
`"null"` means that model values will be set to `null` instead of being removed.
836+
837+
`"empty"` means empty strings, `""`, for model values that has the `string` type, `{}` for model
838+
values with `object` type and `[]` for `array` type. All other types will be treated as `"remove"`.
836839
840+
`"remove"` deletes the property. This is the default.
837841
842+
`"retain"` keeps the value of the property event though the field is no longer in the form or being
843+
vaidated before submit.
844+
845+
If you'd like to set the destroyStrategy for
846+
an entire form, add it to the [globalOptions](#global-options)
838847
839848
840849
Specific options and types
@@ -1581,7 +1590,7 @@ function FormCtrl($scope) {
15811590
"eligible",
15821591
{
15831592
type: "conditional",
1584-
condition: "model.person.eligible",
1593+
condition: "model.person.eligible",
15851594
items: [
15861595
"code"
15871596
]

src/directives/schema-form.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,10 @@ angular.module('schemaForm')
7272
// they have been removed from the DOM
7373
// https://github.com/Textalk/angular-schema-form/issues/200
7474
if (childScope) {
75+
// Destroy strategy should not be acted upon
76+
scope.externalDestructionInProgress = true;
7577
childScope.$destroy();
78+
scope.externalDestructionInProgress = false;
7679
}
7780
childScope = scope.$new();
7881

@@ -162,7 +165,16 @@ angular.module('schemaForm')
162165
});
163166

164167
scope.$on('$destroy', function() {
165-
sfRetainModel.setFlag(true);
168+
console.log('Total schema form destruction in progress.');
169+
// Each field listens to the $destroy event so that it can remove any value
170+
// from the model if that field is removed from the form. This is the default
171+
// destroy strategy. But if the entire form (or at least the part we're on)
172+
// gets removed, like when routing away to another page, then we definetly want to
173+
// keep the model intact. So therefore we set a flag to tell the others it's time to just
174+
// let it be.
175+
scope.externalDestructionInProgress = true;
176+
//scope.$broadcast('externalDestroy')
177+
//sfRetainModel.setFlag(true);
166178
});
167179
}
168180
};

src/directives/schema-validate.js

+40-15
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ angular.module('schemaForm').directive('schemaValidate', ['sfValidator', 'sfSele
103103
});
104104

105105

106-
var DEFAULT_DESTROY_STRATEGY = getGlobalOptionsDestroyStrategy();
106+
/*var DEFAULT_DESTROY_STRATEGY = getGlobalOptionsDestroyStrategy();
107107
108108
function getGlobalOptionsDestroyStrategy() {
109109
var defaultStrategy = undefined;
@@ -122,14 +122,49 @@ angular.module('schemaForm').directive('schemaValidate', ['sfValidator', 'sfSele
122122
}
123123
}
124124
return defaultStrategy;
125-
}
125+
}*/
126+
126127

127128
// Clean up the model when the corresponding form field is $destroy-ed.
128129
// Default behavior can be supplied as a globalOption, and behavior can be overridden in the form definition.
129130
scope.$on('$destroy', function() {
131+
console.log('Schema validate destroy', scope.externalDestructionInProgress);
132+
133+
// If the entire schema form is destroyed we don't touch the model
134+
if (!scope.externalDestructionInProgress) {
135+
var form = getForm();
136+
var destroyStrategy = form.destroyStrategy ||
137+
(scope.options && scope.options.destroyStrategy) || 'remove';
138+
console.log('going with destroy strategy ', destroyStrategy, scope.options)
139+
// No key no model, and we might have strategy 'retain'
140+
if (form.key && destroyStrategy !== 'retain') {
141+
142+
// Get the object that has the property we wan't to clear.
143+
var obj = scope.model;
144+
if (form.key.length > 1) {
145+
obj = sfSelect(form.key.slice(0, form.key.length - 1), obj);
146+
}
147+
148+
// Type can also be a list in JSON Schema
149+
var type = (form.schema && form.schema.type) || '';
150+
151+
// Empty means '',{} and [] for appropriate types and undefined for the rest
152+
if (destroyStrategy === 'empty' && type.indexOf('string') !== -1) {
153+
obj[form.key.slice(-1)] = '';
154+
} else if (destroyStrategy === 'empty' && type.indexOf('object') !== -1) {
155+
obj[form.key.slice(-1)] = {};
156+
} else if (destroyStrategy === 'empty' && type.indexOf('array') !== -1) {
157+
obj[form.key.slice(-1)] = [];
158+
} else if (destroyStrategy === 'null') {
159+
obj[form.key.slice(-1)] = null;
160+
} else {
161+
delete obj[form.key.slice(-1)];
162+
}
163+
}
164+
}
165+
130166

131-
var form = getForm();
132-
var conditionResult = $parse(form.condition);
167+
/*var conditionResult = $parse(form.condition);
133168
var formModelNotRetained = !sfRetainModel.getFlag();
134169
135170
// If condition is defined and not satisfied and the sfSchema model should not be retained.
@@ -166,18 +201,8 @@ angular.module('schemaForm').directive('schemaValidate', ['sfValidator', 'sfSele
166201
}
167202
sfUnselect(scope.form.key, scope.model, strategy);
168203
}
169-
170-
function getSchemaType() {
171-
var sType;
172-
if (form.schema) {
173-
sType = form.schema.type;
174-
}
175-
else {
176-
sType = null;
177-
}
178-
return sType;
179-
}
180204
}
205+
*/
181206
});
182207

183208

0 commit comments

Comments
 (0)