@openui5/sap.ui.core
Version:
OpenUI5 Core Library sap.ui.core
870 lines (806 loc) • 28.3 kB
JavaScript
/*!
* OpenUI5
* (c) Copyright 2009-2023 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/ui/base/EventProvider',
'./ChangeReason',
'./DataState',
"sap/base/Log",
"sap/base/util/each"
],
function(EventProvider, ChangeReason, DataState, Log, each) {
"use strict";
var timeout;
var aDataStateCallbacks = [];
/**
* Constructor for Binding class.
*
* @class
* The Binding is the object, which holds the necessary information for a data binding,
* like the binding path and the binding context, and acts like an interface to the
* model for the control, so it is the event provider for changes in the data model
* and provides getters for accessing properties or lists.
*
* @param {sap.ui.model.Model} oModel The model
* @param {string} sPath The path
* @param {sap.ui.model.Context} oContext The context object
* @param {object} [mParameters] Additional, implementation-specific parameters
* @abstract
* @public
* @alias sap.ui.model.Binding
* @extends sap.ui.base.EventProvider
*/
var Binding = EventProvider.extend("sap.ui.model.Binding", /** @lends sap.ui.model.Binding.prototype */ {
constructor : function(oModel, sPath, oContext, mParameters){
EventProvider.apply(this);
this.oModel = oModel;
this.bRelative = !sPath.startsWith('/');
this.sPath = sPath;
this.oContext = oContext;
this.vMessages = undefined;
this.mParameters = mParameters;
this.bInitial = false;
this.bSuspended = false;
this.oDataState = null;
// whether this binding does not propagate model messages to the control
this.bIgnoreMessages = undefined;
},
metadata : {
"abstract" : true,
publicMethods : [
// methods
"getPath", "getContext", "getModel", "attachChange", "detachChange", "refresh", "isInitial",
"attachDataStateChange","detachDataStateChange",
"attachAggregatedDataStateChange", "detachAggregatedDataStateChange",
"attachDataRequested","detachDataRequested","attachDataReceived","detachDataReceived","suspend","resume", "isSuspended"
]
}
});
/**
* The <code>dataRequested</code> event is fired, when data was requested from a backend.
*
* Note: Subclasses might add additional parameters to the event object. Optional parameters can
* be omitted.
*
* @name sap.ui.model.Binding#dataRequested
* @event
* @param {sap.ui.base.Event} oEvent
* The event object
* @param {sap.ui.base.EventProvider} oEvent.getSource
* The object on which the event initially occurred
* @param {object} oEvent.getParameters
* Object containing all event parameters
* @public
*/
/**
* The <code>dataReceived</code> event is fired, when data was received from a backend.
*
* This event may also be fired when an error occurred.
*
* Note: Subclasses might add additional parameters to the event object. Optional parameters can
* be omitted.
*
* @name sap.ui.model.Binding#dataReceived
* @event
* @param {sap.ui.base.Event} oEvent
* The event object
* @param {sap.ui.base.EventProvider} oEvent.getSource
* The object on which the event initially occurred
* @param {object} oEvent.getParameters
* Object containing all event parameters
* @param {string} [oEvent.getParameters.data]
* The data received; is <code>undefined</code> in error cases
* @public
*/
/**
* The <code>change</code> event is fired, when the model data are changed. The optional
* <code>reason</code> parameter of the event provides a hint where the change came from.
*
* Note: Subclasses might add additional parameters to the event object.
*
* @name sap.ui.model.Binding#change
* @event
* @param {sap.ui.base.Event} oEvent
* The event object
* @param {sap.ui.base.EventProvider} oEvent.getSource
* The object on which the event initially occurred
* @param {object} oEvent.getParameters
* Object containing all event parameters
* @param {string} [oEvent.getParameters.reason]
* A string stating the reason for the data change; some change reasons can be found in
* {@link sap.ui.model.ChangeReason}, but there may be additional reasons specified by a
* specific model implementation
* @public
*/
/**
* The <code>DataStateChange</code> event is fired when the <code>DataState</code> of the
* binding has changed.
*
* Note: Subclasses might add additional parameters to the event object. Optional parameters can
* be omitted.
*
* @name sap.ui.model.Binding#DataStateChange
* @event
* @param {sap.ui.base.Event} oEvent
* The event object
* @param {sap.ui.base.EventProvider} oEvent.getSource
* The object on which the event initially occurred
* @param {object} oEvent.getParameters
* Object containing all event parameters
* @param {sap.ui.model.DataState} [oEvent.getParameters.dataState]
* The <code>DataState</code> object of the binding
* @protected
*/
/**
* The <code>AggregatedDataStateChange</code> event is fired asynchronously when all
* <code>datastateChange</code>s within the actual stack are done.
*
* Note: Subclasses might add additional parameters to the event object. Optional parameters can
* be omitted.
*
* @name sap.ui.model.Binding#AggregatedDataStateChange
* @event
* @param {sap.ui.base.Event} oEvent
* The event object
* @param {sap.ui.base.EventProvider} oEvent.getSource
* The object on which the event initially occurred
* @param {object} oEvent.getParameters
* Object containing all event parameters
* @param {sap.ui.model.DataState} [oEvent.getParameters.dataState]
* The <code>DataState</code> object of the binding
* @protected
*/
// Getter
/**
* Returns the model path to which this binding binds.
*
* Might be a relative or absolute path. If it is relative, it will be resolved relative
* to the context as returned by {@link #getContext}.
*
* @returns {string} Binding path
* @public
*/
Binding.prototype.getPath = function() {
return this.sPath;
};
/**
* Returns the model context in which this binding will be resolved.
*
* If the binding path is absolute, the context is not relevant.
*
* @returns {sap.ui.model.Context} Context object
* @public
*/
Binding.prototype.getContext = function() {
return this.oContext;
};
/**
* Setter for a new context.
*
* @param {sap.ui.model.Context} oContext
* The new context object
* @param {Object<string,any>} [mParameters]
* Additional map of binding specific parameters
* @param {string} [mParameters.detailedReason]
* A detailed reason for the {@link #event:change change} event
*
* @private
*/
Binding.prototype.setContext = function (oContext, mParameters) {
var mChangeParameters;
if (this.oContext != oContext) {
sap.ui.getCore().getMessageManager()
.removeMessages(this.getDataState().getControlMessages(), true);
this.oContext = oContext;
this.getDataState().reset();
this.checkDataState();
mChangeParameters = {reason : ChangeReason.Context};
if (mParameters && mParameters.detailedReason) {
mChangeParameters.detailedReason = mParameters.detailedReason;
}
this._fireChange(mChangeParameters);
}
};
/**
* Getter for current active messages.
* @return {Object} The context object
*/
Binding.prototype.getMessages = function() {
return this.vMessages;
};
/**
* Returns the data state for this binding.
* @return {sap.ui.model.DataState} The data state
*/
Binding.prototype.getDataState = function() {
if (!this.oDataState) {
this.oDataState = new DataState();
}
return this.oDataState;
};
/**
* Returns the model to which this binding belongs.
*
* @returns {sap.ui.model.Model} Model to which this binding belongs
* @public
*/
Binding.prototype.getModel = function() {
return this.oModel;
};
/**
* Provides the resolved path for this binding's path and context and returns it, or
* <code>undefined</code> if the binding is not resolved or has no model.
*
* @returns {string|undefined} The resolved path
*
* @public
* @since 1.88.0
*/
Binding.prototype.getResolvedPath = function () {
return this.oModel ? this.oModel.resolve(this.sPath, this.oContext) : undefined;
};
/**
* Whether this binding does not propagate model messages to the control. By default, all
* bindings propagate messages. If a binding wants to support this feature, it has to override
* {@link #supportsIgnoreMessages}, which returns <code>true</code>.
*
* For example, a binding for a currency code is used in a composite binding for rendering the
* proper number of decimals, but the currency code is not displayed in the attached control. In
* that case, messages for the currency code shall not be displayed at that control, only
* messages for the amount.
*
* @returns {boolean|undefined}
* Whether this binding does not propagate model messages to the control; returns
* <code>undefined</code> if the corresponding binding parameter is not set, which means that
* model messages are propagated to the control
*
* @public
* @since 1.82.0
*/
Binding.prototype.getIgnoreMessages = function () {
if (this.bIgnoreMessages === undefined) {
return undefined;
}
return this.bIgnoreMessages && this.supportsIgnoreMessages();
};
/**
* Sets the indicator whether this binding does not propagate model messages to the control.
*
* @param {boolean} bIgnoreMessages
* Whether this binding does not propagate model messages to the control
*
* @public
* @see #getIgnoreMessages
* @see #supportsIgnoreMessages
* @since 1.82.0
*/
Binding.prototype.setIgnoreMessages = function (bIgnoreMessages) {
this.bIgnoreMessages = bIgnoreMessages;
};
/**
* Whether this binding supports the feature of not propagating model messages to the control.
* The default implementation returns <code>false</code>.
*
* @returns {boolean}
* <code>false</code>; subclasses that support this feature need to override this function and
* need to return <code>true</code>
*
* @public
* @see #getIgnoreMessages
* @see #setIgnoreMessages
* @since 1.82.0
*/
Binding.prototype.supportsIgnoreMessages = function () {
return false;
};
// Eventing and related
/**
* Attaches the <code>fnFunction</code> event handler to the {@link #event:change change} event
* of this <code>sap.ui.model.Model</code>.
*
* When called, the context of the event handler (its <code>this</code>) will be bound to
* <code>oListener</code> if specified, otherwise it will be bound to this
* <code>sap.ui.model.Binding</code> itself.
*
* @param {function} fnFunction
* The function to be called when the event occurs
* @param {object} [oListener]
* Context object to call the event handler with; defaults to this
* <code>sap.ui.model.Binding</code> itself
* @public
*/
Binding.prototype.attachChange = function(fnFunction, oListener) {
if (!this.hasListeners("change")) {
this.oModel.addBinding(this);
}
this.attachEvent("change", fnFunction, oListener);
};
/**
* Detaches event handler <code>fnFunction</code> from the {@link #event:change change} event of
* this <code>sap.ui.model.Binding</code>.
*
* @param {function} fnFunction Function to be called when the event occurs
* @param {object} [oListener] Context object on which the given function had to be called
* @public
*/
Binding.prototype.detachChange = function(fnFunction, oListener) {
this.detachEvent("change", fnFunction, oListener);
if (!this.hasListeners("change")) {
this.oModel.removeBinding(this);
}
};
/**
* Attaches the <code>fnFunction</code> event handler to the
* {@link #event:DataStateChange DataStateChange} event of thi
* <code>sap.ui.model.Binding</code>.
*
* When called, the context of the event handler (its <code>this</code>) will be bound to
* <code>oListener</code> if specified, otherwise it will be bound to this
* <code>sap.ui.model.Binding</code> itself.
*
* @param {function} fnFunction
* Function to be called when the event occurs
* @param {object} [oListener]
* Context object to call the event handler with; defaults to this
* <code>sap.ui.model.Binding</code> itself
* @protected
*/
Binding.prototype.attachDataStateChange = function(fnFunction, oListener) {
this.attachEvent("DataStateChange", fnFunction, oListener);
};
/**
* Detaches event handler <code>fnFunction</code> from the
* {@link #event:DataStateChange DataStateChange} event of this
* <code>sap.ui.model.Binding</code>.
*
* @param {function} fnFunction The function to be called when the event occurs
* @param {object} [oListener] Context object on which the given function had to be called
* @protected
*/
Binding.prototype.detachDataStateChange = function(fnFunction, oListener) {
this.detachEvent("DataStateChange", fnFunction, oListener);
};
/**
* Attaches event handler <code>fnFunction</code> to the
* {@link #event:AggregatedDataStateChange AggregatedDataStateChange} event of this
* <code>sap.ui.model.Binding</code>.
*
* When called, the context of the event handler (its <code>this</code>) will be bound to
* <code>oListener</code> if specified, otherwise it will be bound to this
* <code>sap.ui.model.Binding</code> itself.
*
* @param {function} fnFunction
* The function to be called when the event occurs
* @param {object} [oListener]
* Context object to call the event handler with; defaults to this
* <code>sap.ui.model.Binding</code> itself
* @protected
*/
Binding.prototype.attachAggregatedDataStateChange = function(fnFunction, oListener) {
this.attachEvent("AggregatedDataStateChange", fnFunction, oListener);
};
/**
* Detaches event handler <code>fnFunction</code> from the
* {@link #event:AggregatedDataStateChange AggregatedDataStateChange} event of this
* <code>sap.ui.model.Binding</code>.
*
* @param {function} fnFunction The function to be called when the event occurs
* @param {object} [oListener] Context object on which the given function had to be called
* @protected
*/
Binding.prototype.detachAggregatedDataStateChange = function(fnFunction, oListener) {
this.detachEvent("AggregatedDataStateChange", fnFunction, oListener);
};
/**
* Fires event {@link #event:change change} to attached listeners.
*
* @param {object} oParameters Parameters to pass along with the event.
* @private
*/
Binding.prototype._fireChange = function(oParameters) {
this.fireEvent("change", oParameters);
};
/**
* Attaches event handler <code>fnFunction</code> to the
* {@link #event:dataRequested dataRequested} event of this <code>sap.ui.model.Binding</code>.
*
* When called, the context of the event handler (its <code>this</code>) will be bound to
* <code>oListener</code> if specified, otherwise it will be bound to this
* <code>sap.ui.model.Binding</code> itself.
*
* @param {function} fnFunction
* The function to be called when the event occurs
* @param {object} [oListener]
* Context object to call the event handler with; defaults to this
* <code>sap.ui.model.Binding</code> itself
* @public
*/
Binding.prototype.attachDataRequested = function(fnFunction, oListener) {
this.attachEvent("dataRequested", fnFunction, oListener);
};
/**
* Detaches event handler <code>fnFunction</code> from the
* {@link #event:dataRequested dataRequested} event of this <code>sap.ui.model.Binding</code>.
*
* @param {function} fnFunction The function to be called when the event occurs
* @param {object} [oListener] Context object on which the given function had to be called
* @public
*/
Binding.prototype.detachDataRequested = function(fnFunction, oListener) {
this.detachEvent("dataRequested", fnFunction, oListener);
};
/**
* Fires event {@link #event:dataRequested dataRequested} to attached listeners.
*
* @param {object} oParameters Parameters to pass along with the event
* @protected
*/
Binding.prototype.fireDataRequested = function(oParameters) {
this.fireEvent("dataRequested", oParameters);
};
/**
* Attaches event handler <code>fnFunction</code> to the
* {@link #event:dataReceived dataReceived} event of this <code>sap.ui.model.Binding</code>.
*
* When called, the context of the event handler (its <code>this</code>) will be bound to
* <code>oListener</code> if specified, otherwise it will be bound to this
* <code>sap.ui.model.Binding</code> itself.
*
* @param {function} fnFunction
* Function to be called when the event occurs
* @param {object} [oListener]
* Context object to call the event handler with; defaults to this
* <code>sap.ui.model.Binding</code> itself
* @public
*/
Binding.prototype.attachDataReceived = function(fnFunction, oListener) {
this.attachEvent("dataReceived", fnFunction, oListener);
};
/**
* Detaches event handler <code>fnFunction</code> from the
* {@link #event:dataReceived dataReceived} event of this <code>sap.ui.model.Binding</code>.
*
* @param {function} fnFunction Function to be called when the event occurs
* @param {object} [oListener] Context object on which the given function had to be called
* @public
*/
Binding.prototype.detachDataReceived = function(fnFunction, oListener) {
this.detachEvent("dataReceived", fnFunction, oListener);
};
/**
* Fires event {@link #event:dataReceived dataReceived} to attached listeners.
*
* This event may also be fired when an error occurred.
*
* @param {object} oParameters Parameters to pass along with the event
* @param {object} [oParameters.data] Data received; on error cases it will be undefined
* @protected
*/
Binding.prototype.fireDataReceived = function(oParameters) {
this.fireEvent("dataReceived", oParameters);
};
/**
* Determines if the binding should be updated by comparing the current model against a
* specified model.
*
* @param {object} oModel The model instance to compare against
* @returns {boolean} Whether this binding should be updated
* @protected
*/
Binding.prototype.updateRequired = function(oModel) {
return oModel && this.getModel() === oModel;
};
/**
* Returns whether this binding validates the values that are set on it.
*
* @returns {boolean}
* Whether the binding throws a validation exception when an invalid value is set on it.
* @private
*/
Binding.prototype.hasValidation = function() {
return !!this.getType();
};
/**
* Checks whether an update of this bindings is required. If this is the case the change event
* of the binding is fired. The default implementation just fires the change event when the
* method is called. Subclasses should implement this, if possible.
*
* @param {boolean} [bForceUpdate] Whether the event should be fired when the binding is
* suspended
*
* @private
*/
Binding.prototype.checkUpdate = function(bForceUpdate) {
if (this.bSuspended && !bForceUpdate ) {
return;
}
this._fireChange({reason: ChangeReason.Change});
};
/**
* Refreshes the binding, check whether the model data has been changed and fire change event
* if this is the case. For server side models this should refetch the data from the server.
* To update a control, even if no data has been changed, e.g. to reset a control after failed
* validation, please use the parameter <code>bForceUpdate</code>.
*
* @param {boolean} [bForceUpdate] Update the bound control even if no data has been changed
*
* @public
*/
Binding.prototype.refresh = function(bForceUpdate) {
if (this.bSuspended && !bForceUpdate) {
return;
}
this.checkUpdate(bForceUpdate);
};
/**
* Initialize the binding. The message should be called when creating a binding.
* The default implementation calls checkUpdate(true).
*
* @protected
*/
Binding.prototype.initialize = function() {
if (!this.bSuspended) {
this.checkUpdate(true);
}
return this;
};
/**
* _refresh for compatibility
*
* @param {boolean} [bForceUpdate] Whether an update should be forced
* @private
*/
Binding.prototype._refresh = function(bForceUpdate) {
this.refresh(bForceUpdate);
};
/**
* Returns whether the binding is resolved, which means the binding's path is absolute or the
* binding has a model context.
*
* @returns {boolean} Whether the binding is resolved
*
* @public
* @see #getContext
* @see #getPath
* @see #isRelative
* @since 1.79.0
*/
Binding.prototype.isResolved = function() {
return !this.bRelative || !!this.oContext;
};
/**
* Returns whether the binding is initial, which means it did not get an initial value yet.
*
* @returns {boolean} Whether the binding is initial
* @public
*/
Binding.prototype.isInitial = function() {
return this.bInitial;
};
/**
* Returns whether the binding is relative, which means its path does not start with a slash.
*
* @returns {boolean} Whether the binding is relative
* @public
*/
Binding.prototype.isRelative = function() {
return this.bRelative;
};
/**
* Attach multiple events.
*
* @param {Object.<string, function>} oEvents Events to attach to this binding
* @returns {sap.ui.model.Binding} A reference to itself
* @protected
*/
Binding.prototype.attachEvents = function(oEvents) {
if (!oEvents) {
return this;
}
var that = this;
each(oEvents, function(sEvent, fnHandler) {
var sMethod = "attach" + sEvent.substring(0,1).toUpperCase() + sEvent.substring(1);
if (that[sMethod]) {
that[sMethod](fnHandler);
} else {
Log.warning(that.toString() + " has no handler for event '" + sEvent + "'");
}
});
return this;
};
/**
* Detach multiple events.
*
* @param {Object.<string, function>} oEvents Events to detach from this binding
* @returns {sap.ui.model.Binding} A reference to itself
* @protected
*/
Binding.prototype.detachEvents = function(oEvents) {
if (!oEvents) {
return this;
}
var that = this;
each(oEvents, function(sEvent, fnHandler) {
var sMethod = "detach" + sEvent.substring(0,1).toUpperCase() + sEvent.substring(1);
if (that[sMethod]) {
that[sMethod](fnHandler);
} else {
Log.warning(that.toString() + " has no handler for event '" + sEvent + "'");
}
});
return this;
};
/**
* Attaches event handler <code>fnFunction</code> to the {@link #event:refresh refresh} event of
* this <code>sap.ui.model.Binding</code>.
*
* When called, the context of the event handler (its <code>this</code>) will be bound to
* <code>oListener</code> if specified, otherwise it will be bound to this
* <code>sap.ui.model.Binding</code> itself.
*
* @param {function} fnFunction
* The function to be called when the event occurs
* @param {object} [oListener]
* Context object to call the event handler with; defaults to this
* <code>sap.ui.model.Binding</code> itself
* @protected
*/
Binding.prototype.attachRefresh = function(fnFunction, oListener) {
this.attachEvent("refresh", fnFunction, oListener);
};
/**
* Detaches event handler <code>fnFunction</code> from the {@link #event:refresh refresh} event
* of this <code>sap.ui.model.Binding</code>.
*
* @param {function} fnFunction The function to be called when the event occurs
* @param {object} [oListener] Object on which to call the given function.
* @protected
*/
Binding.prototype.detachRefresh = function(fnFunction, oListener) {
this.detachEvent("refresh", fnFunction, oListener);
};
/**
* Fires event {@link #event:refresh refresh} to attached listeners.
*
* @param {object} [oParameters] The arguments to pass along with the event
* @private
*/
Binding.prototype._fireRefresh = function(oParameters) {
this.fireEvent("refresh", oParameters);
};
/**
* Suspends the binding update. No change events will be fired.
*
* A refresh call with bForceUpdate set to true will also update the binding and fire a change
* in suspended mode. Special operations on bindings, which require updates to work properly
* (as paging or filtering in list bindings) will also update and cause a change event although
* the binding is suspended.
*
* @public
*/
Binding.prototype.suspend = function() {
this.bSuspended = true;
};
/**
* Returns true if the binding is suspended or false if not.
*
* @returns {boolean} Whether the binding is suspended
* @public
*/
Binding.prototype.isSuspended = function() {
return this.bSuspended;
};
/**
* Resumes the binding update. Change events will be fired again.
*
* When the binding is resumed, a change event will be fired immediately if the data has
* changed while the binding was suspended. For server-side models, a request to the server will
* be triggered if a refresh was requested while the binding was suspended.
*
* @public
*/
Binding.prototype.resume = function() {
this.bSuspended = false;
this.checkUpdate();
};
/**
* Removes all control messages for this binding from the MessageManager in addition to the
* standard clean-up tasks.
* @see sap.ui.base.EventProvider#destroy
*
* @public
*/
Binding.prototype.destroy = function() {
var oDataState = this.oDataState;
if (this.bIsBeingDestroyed) { // avoid endless recursion
return;
}
this.bIsBeingDestroyed = true;
if (oDataState) {
sap.ui.getCore().getMessageManager()
.removeMessages(oDataState.getControlMessages(), true);
oDataState.setModelMessages();
if (oDataState.changed()) {
// notify controls synchronously that data state changed
this.fireEvent("DataStateChange", {dataState : oDataState});
this.fireEvent("AggregatedDataStateChange", {dataState : oDataState});
}
delete this.oDataState;
}
EventProvider.prototype.destroy.apply(this, arguments);
};
/**
* Checks whether an update of the data state of this binding is required.
*
* @param {map} [mPaths] A Map of paths to check if update needed
* @private
*/
Binding.prototype.checkDataState = function(mPaths) {
this._checkDataState(this.getResolvedPath(), mPaths);
};
/**
* Checks whether an update of the data state of this binding is required with the given path.
*
* @param {string} sResolvedPath With help of the connected model resolved path
* @param {map} [mPaths] A Map of paths to check if update needed
* @private
*/
Binding.prototype._checkDataState = function(sResolvedPath, mPaths) {
if (!mPaths || sResolvedPath && sResolvedPath in mPaths) {
var that = this;
var oDataState = this.getDataState();
var fireChange = function() {
that.fireEvent("AggregatedDataStateChange", { dataState: oDataState });
oDataState.changed(false);
that.bFiredAsync = false;
};
if (!this.getIgnoreMessages()) {
this._checkDataStateMessages(oDataState, sResolvedPath);
}
if (oDataState && oDataState.changed()) {
if (this.mEventRegistry["DataStateChange"]) {
this.fireEvent("DataStateChange", { dataState: oDataState });
}
if (this.bIsBeingDestroyed) {
fireChange();
} else if (this.mEventRegistry["AggregatedDataStateChange"] && !this.bFiredAsync) {
fireDataStateChangeAsync(fireChange);
this.bFiredAsync = true;
}
}
}
};
/**
* Sets the given data state's model messages to the messages for the given resolved path in the
* binding's model.
*
* @param {sap.ui.model.DataState} oDataState The binding's data state
* @param {string} [sResolvedPath] The binding's resolved path
* @private
*/
Binding.prototype._checkDataStateMessages = function(oDataState, sResolvedPath) {
if (sResolvedPath) {
oDataState.setModelMessages(this.oModel.getMessagesByPath(sResolvedPath));
} else {
oDataState.setModelMessages([]);
}
};
function fireDataStateChangeAsync(callback) {
if (!timeout) {
timeout = setTimeout(function() {
timeout = undefined;
var aCallbacksCopy = aDataStateCallbacks;
aDataStateCallbacks = [];
aCallbacksCopy.forEach(function(cb) {
cb();
});
}, 0);
}
aDataStateCallbacks.push(callback);
}
return Binding;
});