uistate
directory. Simply expose the contents of the directory with your webserver and use your browser to navigate to index.html
. A screenshot is shown below:sap.ui.layout.Splitter
)sap.ui.table.Table
showing the Name and Country of a list of companies.sap.m.Panel
which shows the Company Name as title. The Panel is expandable
and expanded
by default. Inside the panel we can see the company's phone number.sap.m.IconTabBar
with 2 tabs:Euismod Ac Fermentum Corp.
. Adjust the width of the column by dragging the right end of its header to the right until the full company name is visible.Congo, the Democratic Republic of the
. Adjust of that column too so the full name is visible.LocalStorageJSONModel
] to manage UI StateLocalStorageJSONModel
.manifest.json
, so it's instantiated automatically as the application starts, and becomes available throughout the application as uistate
. "uistate": {
"type": "ui5tips.utils.LocalStorageJSONModel",
"dataSource": "uistateTemplate"
}
uistateTemplate
data source: "uistateTemplate": {
"uri": "data/uistateTemplate.json",
"type": "JSON"
}
data/uistateTemplate.json
:{
"autoSaveTimeout": 1000,
"storagePrefix": "uistate",
"template": {
"appSettings": {
"sidebar": {
"splitterSize": "431px",
"columns": {
"name": {
"width": "190px"
},
"country": {
"width": "190px"
}
}
},
"detailpage": {
"panel": {
"expanded": true
},
"tabContainer": {
"selectedTab": "details"
}
}
}
}
}
LocalStorageJSONModel
are described in the LocalStorageJSONModel
wiki page.autoSaveTimeout
is relevant - for this example, the value is assigned 1000
and this means that if the state of the model is changed, there will be a 1000
ms (1 second) waiting period after which the data from the model is persisted in the Browser's local storage.LocalStorageJSONModel
wiki page for a detailed discussion of the template and model initialization.LocalStorageJSONModel
wiki page has some general remarks and clarifications about UI5 data binding. But it may not be entirely clear how to practically organize it to manage UI state. After all, even a simple example like the sample application we discuss here already has 5 distinct UI properties that the user can change.data/uistateTemplate.json
, you'll notice that the template
contains a applicationConfig
key which itself has two keys: one to maintain all settings for the sidebar
and one for all settings for the detailpage
: "template": {
"appSettings": {
"sidebar": {
...
},
"detailpage": {
...
}
}
}
detail
page: "detailpage": {
"panel": {
"expanded": true
},
"tabContainer": {
"selectedTab": "details"
}
}
DetailPage.view.xml
<layout:FixFlex binding="{uistate>detailpage}">
<layout:fixContent>
<m:Panel
expandable="true"
expandAnimation="false"
binding="{uistate>panel}"
expanded="{uistate>expanded}"
headerText="{companies>CompanyName}"
>
<m:content>
<m:Text text="Phone: {companies>Phone}"/>
</m:content>
</m:Panel>
</layout:fixContent>
<layout:flexContent>
<m:IconTabBar
stretchContentHeight="true"
applyContentPadding="false"
expandable="false"
binding="{uistate>tabContainer}"
selectedKey="{uistate>selectedTab}"
>
<m:items>
<core:Fragment fragmentName="ui5tips.components.detailpage.DetailsIconTabFilter" type="XML" />
<core:Fragment fragmentName="ui5tips.components.detailpage.DepartmentsIconTabFilter" type="XML" />
</m:items>
</m:IconTabBar>
</layout:flexContent>
</layout:FixFlex>
sap.ui.layout.FixFlex
. But it might just as well have been another type of container, like, say, a sap.m.Page
. Another example might be the tabs. In this sample application we chose the sap.m.IconTabBar
and in the future we might change that to the sap.m.TabContainer
. While these are functionally similar components, certain details, like property names and aggregation names might be different. "template": {
"appSettings": {
"detailpage": {
"tabContainer": {
"selectedTab": "details"
}
}
}
}
uistate>/appSettings/detailpage/tabContainer/selectedTab
. Obviously, in a realistic application we would have many properties and the UI code would soon become littered with these very long paths.App.view.xml
: <m:App
id="app"
binding="{uistate>/appSettings}"
>
<m:pages>
<mvc:XMLView viewName="ui5tips.components.mainpage.MainPage"/>
</m:pages>
</m:App>
binding
property on the sap.m.App
is bound to uistate>/appSettings
. What this means is that relative bindings for the uistate
model that occur on that component itself, but also to any components that are nested within it, will be resolved against uistate>/appSettings
.sap.m.App
. If we look at that: <m:Page title="UIState App">
...
<layout:Splitter>
<mvc:XMLView id="sideBar" viewName="ui5tips.components.sidebar.SideBar">
<mvc:layoutData>
<layout:SplitterLayoutData size="{uistate>sidebar/splitterSize}"/>
</mvc:layoutData>
</mvc:XMLView>
<mvc:XMLView id="detailPage" viewName="ui5tips.components.detailpage.DetailPage"/>
</layout:Splitter>
</m:Page>
uistate
model here - it is the size
property of the sap.ui.layout.SplitterLayoutData
object, which is bound to uistate>sidebar/splitterSize
. As you can see, that binding refers also to the uistate
model, but as it does not start with a /
, it is a relative path. So, UI5 will try to resolve it by going up the UI tree, and it will then find the scope from the uistate
model that is established by the element binding in App.view.xml
.App.view.xml
, the binding was to uistate>/appSettings
. If we resolve uistate>sidebar/splitterSize
against that, the effective path will become uistate>/appSettings/sidebar/splitterSize
.DetailPage.view.xml
, we notice that its top sap.layout.FixFlex
component was bound to uistate>detailpage
, effectively letting all relative bindings to the uistate
model inside it to be resolved to uistate>/appSettings/detailpage
.You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
7 | |
6 | |
6 | |
5 | |
4 | |
4 | |
4 | |
4 | |
4 | |
4 |