Undo changes in sap.ui.model.json.JSONModel

Sometimes there is a need to track changes in a sap.ui.model.json.JSONModel from a certain point in time and be able to roll back these changes.

Function

sap.ui.define([
	"sap/ui/model/json/JSONModel",
	"sap/base/util/deepClone",
	"sap/base/util/deepEqual"
], function(JSONModel, deepClone, deepEqual) {
	"use strict";

	return JSONModel.extend("<PROJECT_PATH>.model.<NAME>", {

		/**
		 * @class <NAME>
		 * @summary <SUMMARY>
		 * @extends sap.ui.model.json.JSONModel
		 */
		constructor: function() {
			JSONModel.prototype.constructor.call(this, {
				propertyA: undefined,
				propertyB: undefined,
				propertyC: undefined
			});

		},
		/**
		 * @memberOf <NAME>
		 * @description placeholder function - replace with the relevant business logic
		 * @public
		 */
		readData: function() {
			this.setData({
				propertyA: new Date('1995-12-17T03:24:00'),
				propertyB: "INITIAL",
				propertyC: 44
			});
			this._createUndoObject();
		},
		/** 
		 * @memberOf <NAME>
		 * @description creating a deep clone of the model data to be able to determine changes afterwards
		 */
		_createUndoObject: function() {
			this.oUndoObject = deepClone(this.getData()); //maybe adjust maxDepth parameter
		},
		/** 
		 * @memberOf <NAME>
		 * @description undo changes
		 */
		undo: function() {
			this.setData(this.oUndoObject);
		},
		/** 
		 * @memberOf <NAME>
		 * @description Check if there are changes
		 */
		hasChanges: function() {
			var bHasChanges = !deepEqual(this.oUndoObject, this.getData());
			return bHasChanges;
		}

	});
});

Example

			var oModel = new UndoModel();
			oModel.readData();
			oModel.hasChanges();
			//Expected output: false
			oModel.setProperty("/propertyB", "CHANGE");
			oModel.hasChanges();
			//Expected output: true
			oModel.getProperty("/propertyB");
			//Expected output: 'CHANGE'
			oModel.undo();
			oModel.hasChanges();
			//Expected output: false
			oModel.getProperty("/propertyB");
			//Expected output: 'INITIAL'

Leave a Reply

Your email address will not be published. Required fields are marked *