diff --git a/platform/commonUI/edit/bundle.json b/platform/commonUI/edit/bundle.json index eccaeaf787..aebca5ff92 100644 --- a/platform/commonUI/edit/bundle.json +++ b/platform/commonUI/edit/bundle.json @@ -10,7 +10,7 @@ { "key": "EditController", "implementation": "controllers/EditController.js", - "depends": [ "$scope", "navigationService" ] + "depends": [ "$scope", "$q", "navigationService" ] }, { "key": "EditActionController", diff --git a/platform/commonUI/edit/src/capabilities/EditorCapability.js b/platform/commonUI/edit/src/capabilities/EditorCapability.js index 5ac88d0b68..2c68afd0f4 100644 --- a/platform/commonUI/edit/src/capabilities/EditorCapability.js +++ b/platform/commonUI/edit/src/capabilities/EditorCapability.js @@ -70,14 +70,15 @@ define( * Save any changes that have been made to this domain object * (as well as to others that might have been retrieved and * modified during the editing session) + * @param {boolean} nonrecursive if true, save only this + * object (and not other objects with associated changes) * @returns {Promise} a promise that will be fulfilled after * persistence has completed. */ - save: function () { - return resolvePromise(doMutate()) - .then(doPersist) - .then(markClean) - .then(saveOthers); + save: function (nonrecursive) { + return nonrecursive ? + resolvePromise(doMutate()).then(doPersist) : + resolvePromise(cache.saveAll()); }, /** * Cancel editing; Discard any changes that have been made to diff --git a/platform/commonUI/edit/src/controllers/EditController.js b/platform/commonUI/edit/src/controllers/EditController.js index cf07797429..2654e17f47 100644 --- a/platform/commonUI/edit/src/controllers/EditController.js +++ b/platform/commonUI/edit/src/controllers/EditController.js @@ -14,12 +14,12 @@ define( * navigated domain object into the scope. * @constructor */ - function EditController($scope, navigationService) { + function EditController($scope, $q, navigationService) { function setNavigation(domainObject) { // Wrap the domain object such that all mutation is // confined to edit mode (until Save) $scope.navigatedObject = - domainObject && new EditableDomainObject(domainObject); + domainObject && new EditableDomainObject(domainObject, $q); } setNavigation(navigationService.getNavigation()); diff --git a/platform/commonUI/edit/src/objects/EditableDomainObject.js b/platform/commonUI/edit/src/objects/EditableDomainObject.js index 4e3363c8e9..a7a4e7be3d 100644 --- a/platform/commonUI/edit/src/objects/EditableDomainObject.js +++ b/platform/commonUI/edit/src/objects/EditableDomainObject.js @@ -48,7 +48,7 @@ define( * and provides a "working copy" of the object's * model to allow changes to be easily cancelled. */ - function EditableDomainObject(domainObject) { + function EditableDomainObject(domainObject, $q) { // The cache will hold all domain objects reached from // the initial EditableDomainObject; this ensures that // different versions of the same editable domain object @@ -81,7 +81,7 @@ define( return editableObject; } - cache = new EditableDomainObjectCache(EditableDomainObjectImpl); + cache = new EditableDomainObjectCache(EditableDomainObjectImpl, $q); return cache.getEditableObject(domainObject); } diff --git a/platform/commonUI/edit/src/objects/EditableDomainObjectCache.js b/platform/commonUI/edit/src/objects/EditableDomainObjectCache.js index 3509b9675a..a342fcdad8 100644 --- a/platform/commonUI/edit/src/objects/EditableDomainObjectCache.js +++ b/platform/commonUI/edit/src/objects/EditableDomainObjectCache.js @@ -29,10 +29,11 @@ define( * constructor function which takes a regular domain object as * an argument, and returns an editable domain object as its * result. + * @param $q Angular's $q, for promise handling * @constructor * @memberof module:editor/object/editable-domain-object-cache */ - function EditableDomainObjectCache(EditableDomainObject) { + function EditableDomainObjectCache(EditableDomainObject, $q) { var cache = new EditableModelCache(), dirty = {}, root; @@ -88,23 +89,20 @@ define( * Initiate a save on all objects that have been cached. */ saveAll: function () { - var object; + // Get a list of all dirty objects + var objects = Object.keys(dirty).map(function (k) { + return dirty[k]; + }); + + // Clear dirty set, since we're about to save. + dirty = {}; // Most save logic is handled by the "editor.completion" - // capability, but this in turn will typically invoke - // Save All. An infinite loop is avoided by marking - // objects as clean as we go. - - while (Object.keys(dirty).length > 0) { - // Pick the first dirty object - object = dirty[Object.keys(dirty)[0]]; - - // Mark non-dirty to avoid successive invocations - this.markClean(object); - - // Invoke its save behavior - object.getCapability('editor').save(); - } + // capability, so that is delegated here. + return $q.all(objects.map(function (object) { + // Save; pass a nonrecursive flag to avoid looping + return object.getCapability('editor').save(true); + })); } }; }