UNPKG

@openui5/sap.ui.core

Version:

OpenUI5 Core Library sap.ui.core

266 lines (242 loc) 8.46 kB
/*! * 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; });