@openui5/sap.ui.core
Version:
OpenUI5 Core Library sap.ui.core
266 lines (242 loc) • 8.46 kB
JavaScript
/*!
* OpenUI5
* (c) Copyright 2026 SAP SE or an SAP affiliate company.
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
*/
/*eslint-disable max-len */
// Provides an abstraction for model bindings
sap.ui.define([
"sap/base/util/isPlainObject",
"sap/ui/base/Object"
], function (isPlainObject, BaseObject) {
"use strict";
/**
* Constructor for Context class. The constructor must only be called by model-internal methods.
*
* @class
* The Context is a pointer to an object in the model data. A relative binding needs a context
* as a reference point in order to resolve its path; without a context, a relative binding is
* unresolved and does not point to model data. Context instances can, for example, be created
* in the following ways:
* <ul>
* <li>by a {@link sap.ui.model.ListBinding} for each list entry,</li>
* <li>as the single context associated with a {@link sap.ui.model.ContextBinding},</li>
* <li>by calling {@link sap.ui.model.Model#createBindingContext}.</li>
* </ul>
*
* For more information on the concept of data binding and binding contexts, see
* {@link topic:e2e6f4127fe4450ab3cf1339c42ee832 documentation on binding syntax}.
*
* @param {sap.ui.model.Model} oModel the model
* @param {string} sPath the binding path
* @public
* @alias sap.ui.model.Context
* @extends sap.ui.base.Object
*/
var Context = BaseObject.extend("sap.ui.model.Context", /** @lends sap.ui.model.Context.prototype */ {
constructor : function(oModel, sPath) {
BaseObject.apply(this);
this.oModel = oModel;
this.sPath = sPath;
this.bForceRefresh = false;
this.sDeepPath = "";
},
metadata : {
publicMethods : [
"getModel", "getPath", "getProperty", "getObject"
]
}
});
// Getter
/**
* Getter for model
* @public
* @return {sap.ui.model.Model} the model
*/
Context.prototype.getModel = function() {
return this.oModel;
};
/**
* Getter for path of the context itself or a subpath
* @public
* @param {string} [sPath] the binding path (optional)
* @return {string} the binding path
*/
Context.prototype.getPath = function(sPath) {
return this.sPath + (sPath ? "/" + sPath : "");
};
/**
* Gets the property with the given relative binding path
* @public
* @param {string} sPath the binding path
* @return {any} the property value
*/
Context.prototype.getProperty = function(sPath) {
return this.oModel.getProperty(sPath, this);
};
/**
* Sets the given value for the property with the given binding path relative to this context in the model.
*
* @param {string} sPath
* The binding path
* @param {any} vValue
* The value to set
* @param {string} [sGroupId]
* Not used in default implementation; may be used by sub classes
* @param {boolean} [bRetry]
* Not used in default implementation; may be used by sub classes
* @throws {Error}
* If the value cannot be set because this context does not refer to an entry in the model data
* @private
*/
Context.prototype.setProperty = function(sPath, vValue, sGroupId, bRetry) {
if (!this.oModel.setProperty(sPath, vValue, this, /*bAsyncUpdate*/ true)) {
throw new Error("Cannot set the value " + vValue + " for the property " + sPath + " as the context path "
+ this.getPath() + " does not refer to an entry in the model data.");
}
};
/**
* Gets the (model-dependent) object the context points to, or the object with the given relative binding path.
*
* @param {string|object} [vPath] the binding path as a string, or if an object is provided,
* it is treated as additional parameters (same as <code>mParameters</code>)
* @param {object} [mParameters] additional model-specific parameters
* @returns {any} the context object
*
* @public
*/
Context.prototype.getObject = function(vPath, mParameters) {
if (isPlainObject(vPath)) {
mParameters = vPath;
vPath = undefined;
}
return this.oModel.getObject(vPath, this, mParameters);
};
/**
* Sets the force refresh flag of the context. If this is set, the context will force a refresh of dependent
* bindings, when the context is propagated.
*
* @deprecated since 1.93.0; only supported by the OData V2 Model; use V2 specific Context
* instead
* @private
* @param {boolean} bForceRefresh the force refresh flag
*/
Context.prototype.setForceRefresh = function(bForceRefresh) {
this.bForceRefresh = bForceRefresh;
};
/**
* This method returns, whether dependent bindings need to be refreshed.
*
* @deprecated since 1.93.0; only supported by the OData V2 Model; use V2 specific Context
* instead
* @private
* @return {boolean} the force refresh flag
*/
Context.prototype.isRefreshForced = function() {
return this.bForceRefresh;
};
/**
* Sets the preliminary flag of the context. If this is set, the context is not yet linked to actual model
* data, but does just contain path information. This can be used by dependent bindings to send their request
* in parallel to the request of the context binding.
*
* @deprecated since 1.93.0; only supported by the OData V2 Model; use V2 specific Context
* instead
* @private
* @param {boolean} bPreliminary the preliminary flag
*/
Context.prototype.setPreliminary = function(bPreliminary) {
this.bPreliminary = bPreliminary;
};
/**
* This method returns, whether the context is preliminary.
*
* @deprecated since 1.93.0; only supported by the OData V2 Model; use V2 specific Context
* instead
* @private
* @ui5-restricted sap.suite.ui.generic
* @return {boolean} the preliminary flag
*/
Context.prototype.isPreliminary = function() {
return this.bPreliminary;
};
/**
* Sets the updated flag of the context. If this is set, the context was updated. E.g. the path changed from
* a preliminary path to the canonical one.
*
* @deprecated since 1.93.0; only supported by the OData V2 Model; use V2 specific Context
* instead
* @private
* @param {boolean} bUpdated the preliminary flag
*/
Context.prototype.setUpdated = function(bUpdated) {
this.bUpdated = bUpdated;
};
/**
* This method returns, whether the context is updated.
*
* @deprecated since 1.93.0; only supported by the OData V2 Model; use V2 specific Context
* instead
* @private
* @return {boolean} the updated flag
*/
Context.prototype.isUpdated = function() {
return this.bUpdated;
};
/**
* Whether this context has changed. By default this context cannot be changed but subclasses
* can override this behaviour.
*
* @return {boolean} Whether this context has changed
* @private
* @ui5-restricted sap.ui.base.ManagedObject
*/
Context.prototype.hasChanged = function() {
return false;
};
/**
* Compares the two given Contexts. Returns true if the context instances are not equal,
* if the new context is updated or if the new context is refreshed.
*
* @param {sap.ui.model.Context} oOldContext The old Context
* @param {sap.ui.model.Context} oNewContext The new Context
* @return {boolean} Whether oNewContext has changed
* @private
*/
Context.hasChanged = function(oOldContext, oNewContext) {
// The check below is used in ManagedObject.setBindingContext as well to avoid
// a dependency to Context (ManagedObject should be databinding free).
// Both places must kept in sync!
return oOldContext !== oNewContext
|| !!oNewContext && !!oNewContext.hasChanged();
};
/**
* Returns the path of this Context instance.
*
* @returns {string} The path
*/
Context.prototype.toString = function() {
return this.sPath;
};
/**
* Returns messages associated with this context, that is messages belonging to the object
* referred to by this context or a child object of that object. The messages are sorted by
* their {@link sap.ui.core.message.Message#getType type} according to the type's severity in a
* way that messages with highest severity come first.
*
* @returns {sap.ui.core.message.Message[]}
* The messages associated with this context sorted by severity; empty array in case no
* messages exist
* @throws {Error}
* In case the context's model does not implement the method
* {@link sap.ui.model.Model#getMessages}
*
* @public
* @see sap.ui.model.Model#getMessages
* @since 1.76.0
*/
Context.prototype.getMessages = function () {
return this.oModel.getMessages(this);
};
return Context;
});