UNPKG

@openui5/sap.ui.core

Version:

OpenUI5 Core Library sap.ui.core

290 lines (266 loc) 11.2 kB
/*! * OpenUI5 * (c) Copyright 2026 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ // Provides control sap.ui.core.mvc.JSView. sap.ui.define([ './View', './JSViewRenderer', './ViewType', 'sap/base/util/extend', 'sap/base/util/merge', 'sap/ui/base/ManagedObject', 'sap/ui/base/OwnStatics', 'sap/base/Log' ], function(View, JSViewRenderer, ViewType, merge, extend, ManagedObject, OwnStatics, Log) { "use strict"; const { runWithPreprocessors } = OwnStatics.get(ManagedObject); /** * Constructor for a new <code>JSView</code>. * * @class A View defined/constructed by JavaScript code. * * @param {string} [sId] id for the new control, generated automatically if no id is given * @param {object} [mSettings] initial settings for the new control * * @extends sap.ui.core.mvc.View * @version 1.147.0 * @deprecated Since 1.90. Instead use {@link topic:e6bb33d076dc4f23be50c082c271b9f0 Typed Views} * by defining the view class with {@link sap.ui.core.mvc.View.extend View.extend} and * creating the view instances with {@link sap.ui.core.mvc.View.create View.create}. * * @public * @alias sap.ui.core.mvc.JSView */ var JSView = View.extend("sap.ui.core.mvc.JSView", /** @lends sap.ui.core.mvc.JSView.prototype */ { metadata : { library : "sap.ui.core" }, renderer: JSViewRenderer }); /** * Map of already registered JavaScript views (pseudo classes), keyed by their name. * * When a new JSView definition is registered for some name, the definition object * is stored in this map, keyed by that name. * * When a new instance of JSView is created for an already registered view name (class), * then all properties from the corresponding definition object in this map are copied to * the new instance of JSView. * * There's currently no API to remove view definitions from this map. * * @type Object<string,Object> * @private */ var mRegistry = {}; /** * Flag for feature detection of asynchronous loading/rendering. * @public * @readonly * @type {boolean} * @since 1.30 */ JSView.asyncSupport = true; /** * The type of the view used for the <code>sap.ui.view</code> factory * function. This property is used by the parsers to define the specific * view type. * @private */ JSView._sType = ViewType.JS; /** * Creates an instance of the view with the given name (and id). * * @param {object} oOptions An object containing the view configuration options. * @param {string} [oOptions.id] Specifies an ID for the view instance. If no ID is given, an ID will be generated. * @param {string} [oOptions.viewName] Name of the view definition. The view must still be defined using {@link sap.ui.jsview}. * @param {sap.ui.core.mvc.Controller} [oOptions.controller] Controller instance to be used for this view. * The given controller instance overrides the controller defined in the view definition. Sharing a controller instance * between multiple views is not supported. * @public * @static * @deprecated Since 1.90. Use {@link sap.ui.core.mvc.View.create View.create} to create view instances * @since 1.56.0 * @returns {Promise<sap.ui.core.mvc.JSView>} A promise that resolves with the view instance */ JSView.create = function(oOptions) { var mParameters = merge({}, oOptions); // remove unsupported options: for (var sOption in mParameters) { if (sOption === 'definition' || sOption === 'preprocessors') { delete mParameters[sOption]; Log.warning("JSView.create does not support the options definition or preprocessor!"); } } mParameters.type = ViewType.JS; return View.create(mParameters); }; /** * Defines or creates an instance of a JavaScript view. * * The behavior of this method depends on the signature of the call and on the current context. * * <h3>View Definition</h3> * <pre> * sap.ui.jsview(sId, vView); * </pre> * Defines a view of the given name with the given implementation. <code>sId</code> must be the view's name, * <code>vView</code> must be an object and can contain implementations for any of the hooks provided by JSView. * * <h3>View Instantiation (deprecated)</h3> * <pre> * var oView = sap.ui.jsview(vView); * var oView = sap.ui.jsview(vView, bASync); * var oView = sap.ui.jsview(sId, vView); * var oView = sap.ui.jsview(sId, vView, bAsync); * </pre> * Creates an instance of the view with the given name (and id). If no view implementation has been defined * for that view name, a JavaScript module with the same qualified name and with suffix <code>.view.js</code> * will be loaded (required) and executed. The module should register a view definition on execution * (1st. variant above). * * If <code>sId</code> is omitted, an ID will be created automatically. * * When <code>bAsync</code> has a truthy value, the view definition will be read asynchronously, if needed, * but the (incomplete) view instance will be returned immediately. * * <b>Note:</b> Any other call signature will lead to a runtime error. * * @param {string} [sId] ID of the newly created view, only allowed for instance creation * @param {string | object} vView name or implementation of the view. * @param {boolean} [bAsync=false] whether the view source is loaded asynchronously * @public * @static * @deprecated Since 1.56. Instead use {@link topic:e6bb33d076dc4f23be50c082c271b9f0 Typed Views} * by defining the view class with {@link sap.ui.core.mvc.View.extend View.extend} and * creating the view instances with {@link sap.ui.core.mvc.View.create View.create}. * @ui5-global-only * @returns {sap.ui.core.mvc.JSView | undefined} the created JSView instance in the creation case, otherwise undefined */ sap.ui.jsview = function(sId, vView, bAsync) { return viewFactory.apply(this, arguments); }; /** * The old view factory implementation * * @param {string} [sId] ID of the newly created view, only allowed for instance creation * @param {string|object} vView name or implementation of the view * @param {boolean} [bAsync=false] whether the view source is loaded asynchronously * @returns {sap.ui.core.mvc.JSView} the created view instance * @private */ function viewFactory(sId, vView, bAsync) { var mSettings = {}, oView; if (vView && typeof (vView) == "string") { // instantiation sap.ui.jsview("id","name", [async]) mSettings.viewName = vView; if (typeof arguments[2] == "boolean") { mSettings.async = bAsync; } else if (typeof arguments[2] == "object") { // arguments[2] is somehow a controller mSettings.controller = arguments[2]; mSettings.async = !!arguments[3]; // optional } if (mSettings.viewName.startsWith("module:")) { throw Error("Legacy factory sap.ui.jsview doesn't support typed views!"); } oView = new JSView(sId, mSettings); return oView; } else if (vView && typeof (vView) == "object") { // definition sap.ui.jsview("name",definitionObject) // sId is not given, but contains the desired value of sViewName mRegistry[sId] = vView; sap.ui.loader._.declareModule(sId.replace(/\./g, "/") + ".view.js"); Log.warning("For defining views, use typed views with 'sap.ui.core.mvc.View.extend()'."); } else if (arguments.length == 1 && typeof sId == "string" || arguments.length == 2 && typeof arguments[0] == "string" && typeof arguments[1] == "boolean") { // instantiation sap.ui.jsview("name", [async]) mSettings.viewName = arguments[0]; mSettings.async = !!arguments[1]; // optional /*** STEP 1: create View ***/ oView = mSettings.id ? new JSView(mSettings.id, mSettings) : new JSView(mSettings); /*** Step 3B and 4B (create and connect controller) happen in View ***/ return oView; } else { throw new Error( "Wrong arguments ('" + sId + "', '" + vView + "')!" + " Either call sap.ui.jsview([sId,] sViewName) to instantiate a View" + " or sap.ui.jsview(sViewName, oViewImpl) to define a View type."); } } JSView.prototype.initViewSettings = function (mSettings) { var oPromise; Log.warning( "Do not use deprecated sap.ui.core.mvc.JSView: (View: " + (mSettings.id || mSettings.viewName) + "). " + "Use typed views defined by 'sap.ui.core.mvc.View.extend()' and created by 'sap.ui.core.mvc.View.create()'. " + "For further information, have a look at https://sdk.openui5.org/topic/e6bb33d076dc4f23be50c082c271b9f0.", "sap.ui.core.mvc.JSView", null, function () { return { type: "sap.ui.core.mvc.JSView", name: mSettings.viewName }; } ); if (Object.getPrototypeOf(this) === JSView.prototype) { // require view definition if not yet done... if (!mRegistry[mSettings.viewName]) { var sModuleName = mSettings.viewName.replace(/\./g, "/") + ".view"; if (mSettings.async) { oPromise = new Promise(function(resolve, reject) { sap.ui.require([sModuleName], resolve, reject); }); } else { sap.ui.requireSync(sModuleName); // legacy-relevant: Sync path } } // extend 'this' with view from registry which should now or then be available if (mSettings.async) { return Promise.resolve(oPromise).then(function() { extend(this, mRegistry[mSettings.viewName]); }.bind(this)); } extend(this, mRegistry[mSettings.viewName]); } else if (mSettings.async) { return Promise.resolve(); } }; JSView.prototype.onControllerConnected = function(oController) { // temporarily replace any preprocessors, e.g. from an enclosing JSON view runWithPreprocessors(function() { this.applySettings({ content : this.createContent(oController) }); }, { // when auto prefixing is enabled, we add the prefix id: this.getAutoPrefixId() ? this.createId.bind(this) : undefined, settings: this._fnSettingsPreprocessor }, this); }; /** * A method to be implemented by JSViews, returning the flag whether to prefix the IDs of controls * automatically or not, if the controls are created inside the {@link sap.ui.core.mvc.JSView#createContent} * function. By default this feature is not activated. * * You can overwrite this function and return <code>true</code> to activate the automatic prefixing. * * @since 1.15.1 * @returns {boolean} Whether the control IDs should be prefixed automatically * @protected */ /** * A method to be implemented by <code>JSView</code>s, returning the view UI. * * While for declarative view types like <code>XMLView</code> or <code>JSONView</code> the user interface definition * is declared in a separate file, <code>JSView</code>s programmatically constructs the UI. This happens in the * <code>createContent</code> method which every <code>JSView</code> needs to implement. The view implementation * can construct the complete UI in this method, or only return the root control and create the remainder of the UI * lazily later on. * * @returns {sap.ui.core.Control|sap.ui.core.Control[]} A control or array of controls representing the view user interface * @public * @name sap.ui.core.mvc.JSView#createContent * @function */ return JSView; });