[Common UI] Finish JSDoc for edit mode

Complete in-line documentation for bundle
platform/commonUI/edit (Edit Mode), one of the
common user interface bundles being transitioned
for WTD-574.
This commit is contained in:
Victor Woeltjen 2014-11-25 12:50:06 -08:00
parent 4c0e5e963e
commit d950fe14e5
4 changed files with 94 additions and 38 deletions

View File

@ -9,11 +9,15 @@ define(
"use strict"; "use strict";
/** /**
* * Controller which is responsible for populating the scope for
* Edit mode; introduces an editable version of the currently
* navigated domain object into the scope.
* @constructor * @constructor
*/ */
function EditController($scope, navigationService) { function EditController($scope, navigationService) {
function setNavigation(domainObject) { function setNavigation(domainObject) {
// Wrap the domain object such that all mutation is
// confined to edit mode (until Save)
$scope.navigatedObject = $scope.navigatedObject =
domainObject && new EditableDomainObject(domainObject); domainObject && new EditableDomainObject(domainObject);
} }

View File

@ -1,52 +1,71 @@
/*global define*/ /*global define*/
/**
* Wrapper for both "context" and "composition" capabilities;
* ensures that any domain objects reachable in Edit mode
* are also wrapped as EditableDomainObjects
*/
define( define(
[], [],
function () { function () {
'use strict'; 'use strict';
/**
* Wrapper for both "context" and "composition" capabilities;
* ensures that any domain objects reachable in Edit mode
* are also wrapped as EditableDomainObjects.
*
* Meant specifically for use by EditableDomainObject and the
* associated cache; the constructor signature is particular
* to a pattern used there and may contain unused arguments.
*/
return function EditableContextCapability( return function EditableContextCapability(
contextCapability, contextCapability,
editableObject, editableObject,
domainObject, domainObject,
factory cache
) { ) {
var capability = Object.create(contextCapability); var capability = Object.create(contextCapability);
// Check for domain object interface. If something has these
// three methods, we assume it's a domain object.
function isDomainObject(obj) { function isDomainObject(obj) {
return typeof obj.getId === 'function' && return obj !== undefined &&
typeof obj.getId === 'function' &&
typeof obj.getModel === 'function' && typeof obj.getModel === 'function' &&
typeof obj.getCapability === 'function'; typeof obj.getCapability === 'function';
} }
// Check an object returned by the wrapped capability; if it
// is a domain object, we want to make it editable and/or get
// it from the cache of editable domain objects. This will
// prevent changes made in edit mode from modifying the actual
// underlying domain object.
function makeEditableObject(obj) { function makeEditableObject(obj) {
return isDomainObject(obj) ? return isDomainObject(obj) ?
factory.getEditableObject(obj) : cache.getEditableObject(obj) :
obj; obj;
} }
function makeEditable(obj) { // Wrap a returned value (see above); if it's an array, wrap
return Array.isArray(obj) ? // all elements.
obj.map(makeEditableObject) : function makeEditable(returnValue) {
makeEditableObject(obj); return Array.isArray(returnValue) ?
returnValue.map(makeEditableObject) :
makeEditableObject(returnValue);
} }
// Replace all methods; return only editable domain objects. // Wrap a returned value (see above); if it's a promise, wrap
// the resolved value.
function wrapResult(result) {
return result.then ? // promise-like
result.then(makeEditable) :
makeEditable(result);
}
// Wrap all methods; return only editable domain objects.
Object.keys(contextCapability).forEach(function (k) { Object.keys(contextCapability).forEach(function (k) {
capability[k] = function () { capability[k] = function () {
var result = contextCapability[k].apply( return wrapResult(contextCapability[k].apply(
capability, capability,
arguments arguments
); ));
return result.then ? // promise-like
result.then(makeEditable) :
makeEditable(result);
}; };
}); });

View File

@ -1,16 +1,21 @@
/*global define*/ /*global define*/
/**
* Editable Persistence Capability. Overrides the persistence capability
* normally exhibited by a domain object to ensure that changes made
* during edit mode are not immediately stored to the database or other
* backing storage.
*/
define( define(
function () { function () {
'use strict'; 'use strict';
return function EditablePersistenceCapability( /**
* Editable Persistence Capability. Overrides the persistence capability
* normally exhibited by a domain object to ensure that changes made
* during edit mode are not immediately stored to the database or other
* backing storage.
*
* Meant specifically for use by EditableDomainObject and the
* associated cache; the constructor signature is particular
* to a pattern used there and may contain unused arguments.
*/
function EditablePersistenceCapability(
persistenceCapability, persistenceCapability,
editableObject, editableObject,
domainObject, domainObject,
@ -25,6 +30,8 @@ define(
}; };
return persistence; return persistence;
}; }
return EditablePersistenceCapability;
} }
); );

View File

@ -1,19 +1,24 @@
/*global define*/ /*global define,Promise*/
/**
* Implements "save" and "cancel" as capabilities of
* the object. In editing mode, user is seeing/using
* a copy of the object (an EditableDomainObject)
* which is disconnected from persistence; the Save
* and Cancel actions can use this capability to
* propagate changes from edit mode to the underlying
* actual persistable object.
*/
define( define(
[], [],
function () { function () {
'use strict'; 'use strict';
/**
* Implements "save" and "cancel" as capabilities of
* the object. In editing mode, user is seeing/using
* a copy of the object (an EditableDomainObject)
* which is disconnected from persistence; the Save
* and Cancel actions can use this capability to
* propagate changes from edit mode to the underlying
* actual persistable object.
*
* Meant specifically for use by EditableDomainObject and the
* associated cache; the constructor signature is particular
* to a pattern used there and may contain unused arguments.
*/
return function EditorCapability( return function EditorCapability(
persistenceCapability, persistenceCapability,
editableObject, editableObject,
@ -21,31 +26,52 @@ define(
cache cache
) { ) {
// Update the underlying, "real" domain object's model
// with changes made to the copy used for editing.
function doMutate() { function doMutate() {
return domainObject.useCapability('mutation', function () { return domainObject.useCapability('mutation', function () {
return editableObject.getModel(); return editableObject.getModel();
}); });
} }
// Persist the underlying domain object
function doPersist() { function doPersist() {
return persistenceCapability.persist(); return persistenceCapability.persist();
} }
// Save any other objects that have been modified in the cache.
// IMPORTANT: This must not be called until after this object
// has been marked as clean.
function saveOthers() { function saveOthers() {
return cache.saveAll(); return cache.saveAll();
} }
// Indicate that this object has been saved.
function markClean() { function markClean() {
return cache.markClean(editableObject); return cache.markClean(editableObject);
} }
return { return {
/**
* 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)
* @returns {Promise} a promise that will be fulfilled after
* persistence has completed.
*/
save: function () { save: function () {
return Promise.resolve(doMutate()) return Promise.resolve(doMutate())
.then(doPersist) .then(doPersist)
.then(markClean) .then(markClean)
.then(saveOthers); .then(saveOthers);
}, },
/**
* Cancel editing; Discard 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)
* @returns {Promise} a promise that will be fulfilled after
* cancellation has completed.
*/
cancel: function () { cancel: function () {
return Promise.resolve(undefined); return Promise.resolve(undefined);
} }