In this document:
An APS application should use single page views in UX1. The key differences of this technique are as follows.
To be available in the reseller, customer, or service user environment, the application navigation tree must plug into the respective placeholder, for example:
<navigation id="vps-mgmt" label="VPS Management">
<plugs-to id="http://www.parallels.com/ccp/2"/>
<view id="servers" label="Servers" src="ui/servers.js">
...
</navigation>
Note
For a file with the *.js
name extension (unlike .html
), the src
attribute must be specified explicitly.
In the ui/
folder, the bootstrapApp.html
file must exist.
The file is loaded in an IFrame the first
time one of the application views is open. Here is its contents:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
// On the client side, window.location.href provides the path to the page
var url = window.location.href.split('/');
window.dojoConfig = {
packages: [
{name: 'app', location: url.slice(0, -1).join('/')},
{name: 'pacs', location: url.slice(0, -3).join('/')}
]
};
</script>
<script type="text/javascript" src="/aps/2/ui/runtime/client/aps/aps.js"></script>
<script>
require([
"aps/load",
"aps/ready!"
], function(load){
load(["aps/PageContainer"], "aps-frame");
});
</script>
</head>
<body>
<div id="aps-frame" class="ccp-content-body"></div>
</body>
</html>
Note
When building an APS package by means of the aps build
utility, the latter adds the bootstrapApp.html
file if it does not exist in ui/
and at least one element with src="*.js"
is declared inside
the navigation tree plugged into UX1.
When a user switches to another view from the current view, the latter will not be removed from the IFrame. All its embedded widgets are still available in the IFrame.
Warning
For this reason, follow the recommendations on assigning widget IDs unique in scope of the whole application, not only in scope of a view.
The following diagram illustrates how it works.
In UX1, a user opens the view-11 of the App-1 application.
The system creates an IFrame and loads the bootstrapApp.html
file along with the view-11 source code to this IFrame.
Since this point, the view-11 code will be in the IFrame even when the user switches to another view.
The user navigates to the view-12 of the same application.
The system loads the view-12 source code to the IFrame. Since this point, all backward and forward transitions (dash lines) between the two views will be inside the IFrame.
The user goes to the view-21 of the App-2 application.
The system creates an IFrame and loads the bootstrapApp.html
file along with the view-21 source code to this IFrame.
Since this point, the view-21 code will be in the IFrame even when the user switches to another view.
All subsequent forward and backward steps 7-8 and other in the App-2 UI will be processed similar to the steps explained earlier for App-1.
The system removes IFrames when the user re-login to UX1 or refreshes the browser.
Compared with the typical structure of a view in CP, there are a number of differences in the structure of a single page view in UX1:
The view inherits the aps/View module.
The views of an application can share data through the aps.app
object.
A view can create an object in the aps.app
object to share it with other views in the same IFrame.
For example, you can share the aps.app.model
object between all views of the application.
The view inherits a number of flow methods triggered sequentially by UX1 thus implementing
a certain life-cycle. Among the flow methods, the init
method is called
only once to initialize the view, when a user opens it for the first time.
The other methods are called each time the the user comes back to the view. The only mandatory method is init
.
The system loads the widgets of the application views into the root aps/PageContainer
defined
in the bootstrapApp.html file.
Warning
For this reason, do not try to create this container in a view.
Flow methods of a view follow each other or are called by external events as the following diagram presents:
Note
If a notification comes when a popup view is open on the screen, it will not call the onContext
method
of the view. Instead, after the popup view is closed, the onContext
method of the parent view will be called.
The following table briefly explains the flow methods:
METHOD |
PURPOSE |
ACTIVATED |
RETURNS |
---|---|---|---|
* Declare data sources
* Define and initialize data models for widgets
* Define internal widget handlers, for example, cell renders in a grid
* Initialize page layout as a hierarchy of widgets mapped to data models
|
Only once, when the view is loaded into the app IFrame by |
One of the following:
* Hierarchy of widget definitions (recommended)
* Undefined
|
|
Secondary role - for example, prepares widgets before making them visual |
* After the widgets returned by
init are loaded* Every time a user returns back to the view
|
One of the following:
* Deferred promise
* Undefined
|
|
* Get actual data from the data sources
* Update data models
* Update widgets (not required if mapped to a model)
* Show widgets after calling
aps.apsc.hideLoading() |
* After the
onShow promise (if defined) is resolved and
the aps.context object is filled with actual data* A notification is received
|
Undefined |
|
Reset some variables or widgets before hiding the view |
* When the
gotoView method is called* When the user selects another view in UX1
|
Undefined |
Step-by-step demo project illustrates creation of a basic application with single page UI.