sap.ui.model.json.JSONModel
with sap.ui.util.Storage
utility.localstoragemodel
folder and exposing them with your webserver.sap.ui.util.Storage
utility and the sap.ui.model.json.JSONModel
.sap.ui.util.Storage
utilitysap.ui.util.Storage
utility offers a UI5 APIto access the Browser's standard HTML5 Web Storage API. It's a pretty basic, no-nonsense wrapper for managing modest amounts of data based on key/value access.sap.ui.util.Storage
utility directly and code your own logic to control exactly when you want to retrieve and store some data. While there is nothing against that approach, we envisioned something that also works when using models and data binding. manifest.json
: ...,
"models": {
"products": {
"type": "sap.ui.model.json.JSONModel",
"dataSource": "products"
},
"shoppingList": {
"type": "ui5tips.utils.LocalStorageJSONModel",
"dataSource": "shoppingListTemplate"
}
},
...
MainPage.controller.js
, an event handler is attached to listen to the Shopping list's dirtyStateChange
and propertyChange
events, which in turn control certain aspects of the screen logic, such as enabling and disabling the Save and Undo buttons: ...,
initShoppingListModelHandlers: function(){
var shoppingListModel = this.getShoppingListModel();
shoppingListModel.attachDirtyStateChange(function(event){
this.dirtyStateChanged(event.getParameters());
}, this);
shoppingListModel.attachPropertyChange(function(event){
var path = event.getParameter('path');
var context = event.getParameter('context');
var itemsPath = '/items';
if (path === itemsPath || context && context.getPath() === itemsPath) {
this.itemsChanged(shoppingListModel.getProperty(itemsPath));
}
}, this);
},
...
sap.ui.table.Table
control, which only support adding rows through data binding. For example, take a look at ShoppingList.fragment.xml
to see how it gets its rows from the Shopping List model: ...
<table:Table
id="shoppingList"
title="Shopping List"
editable="true"
selectionMode="None"
enableBusyIndicator="true"
visibleRowCountMode="Auto"
rowActionCount="1"
rows="{
path: 'shoppingList>/items'
}"
>
...
Products.fragment.xml
with databinding, which passes the current product and the items from the shopping list to the controller's getShoppingCartRowActionIconSource
formatter function: ...
<table:RowActionItem
binding="{shoppingList>/items}"
icon="{
parts: [
{path: 'products>'},
{path: 'shoppingList>'}
],
formatter: '.getShoppingCartRowActionIconSource'
}"
text="Add to Cart"
press="onCartButtonPressed"
/>
...
getShoppingCartRowActionIconSource
method to obtain an icon, depending on the current product from the product model and all the items in the shopping list model.)ShoppingList.fragment.xml
, the state of the Submit and Clear buttons is enabled depending upon whether the shopping list has any items: ...
<m:contentMiddle>
<m:Button
id="approvalButton"
icon="sap-icon://cart-approval"
tooltip="Send Order"
enabled="{= ${shoppingList>/items}.length > 0 && ${shoppingList>/items/0} !== undefined }"
press="onApproveButtonPressed"
/>
</m:contentMiddle>
<m:contentRight>
<m:Button
id="clearAllButton"
icon="sap-icon://clear-all"
tooltip="Clear Shoppinglist"
enabled="{= ${shoppingList>/items}.length > 0 && ${shoppingList>/items/0} !== undefined}"
press="onClearButtonPressed"
/>
</m:contentRight>
...
sap.ui.model.json.JSONModel
backed by sap.ui.util.Storage
sap.ui.model.json.JSONModel
as a base, and extend it to add a few methods that allow the model's data to be stored and retrieved from sap.ui.util.Storage
.sap.ui.model.json.JSONModel
. This means that in particular, all behavior with regards to databinding will be exactly as with the sap.ui.model.json.JSONModel
.sap.ui.model.ClientModel
, but it turns out that implementing reliable databinding is not as easy as it seems. Or I should say, I took a naive shot at doing that, and failed. While it might be very instructive to try it in earnest, I decided that at this point I am more interested in having a working solution than to learn all the ui5 internals required to succesfully implement databinding.LocalStorageJSONModel
.LocalStorageJSONModel
from the manifest.json
LocalStorageJSONModel
implicitly by declaring it in the manifest.json
: "shoppingList": {
"type": "ui5tips.utils.LocalStorageJSONModel",
"dataSource": "shoppingListTemplate"
}
datasource
called shoppingListTemplate
which is also declared in the manifest.json
: "shoppingListTemplate": {
"uri": "data/shoppingListTemplate.json",
"type": "JSON"
}
datasource
refers to some configuration data stored in data/shoppingListTemplate.json
and its contents are:{
"autoSaveTimeout": -1,
"storagePrefix": "shoppingList",
"template": {
"items": [
]
}
}
LocalStorageJSONModel
constructor. Its properties are:int autoSaveTimeout
: (optional) an integer specifying the number of milliseconds to wait after the last change to the model before automatically saving the model's data to the persistent storage. If this is 0
or less, data is not automatically persisted.string storagePrefix
: (optional) a string that is used to prefix the key under which the models data will be stored in storage. Thesap.ui.util.Storage
constructor takes a storagePrefix, and the LocalStorageJSONModel
takes its own class name for that. But if you have several of these models in one application, you can keep them apart by specifying a specific storagePrefix
here.object template
: (optional) an object that will be used as template data for the model.LocalStorageJSONModel
directlysap.ui.define([
"sap/ui/core/mvc/Controller",
"ui5tips/utils/LocalStorageJSONModel"
],
function(
Controller,
LocalStorageJSONModel
){
"use strict";
var controller = Controller.extend("ui5tips.components.app.App", {
onInit: function(){
var localStorageModel = new LocalStorageJSONModel({
"autoSaveTimeout": -1,
"storagePrefix": "myApp",
"template": {
...data...
}
});
this.getView().setModel(localStorageModel, 'localStorageModel');
}
});
return controller;
});
LocalStorageJSONModel
are:loadFromStorage(template)
: populates the model with the data persisted in the storage. If the template
argument is specified, then the data from the storage is patched with the data in the template. (For more details, see the next section about model initialization and the template). In the sample application, the Undo button action is implemented by calling loadFromStorage()
: onUndoButtonPressed: function(){
var shoppingListModel = this.getShoppingListModel();
shoppingListModel.loadFromStorage();
}
saveToStorage()
: stores the model data to the browser storage. In the sample application, the Save button action is implemented by calling the saveToStorage()
method. onSaveButtonPressed: function(){
var shoppingListModel = this.getShoppingListModel();
shoppingListModel.saveToStorage();
}
deleteFromStorage()
: permanently removes the data from the local storage. Use this if you're sure the application will not need any of the currently stored data anymore.isDirty()
: returns a boolean that indicates whether the current model state is different from what is stored. If it returns true, it means the current state of the model is different from the stored state. Note that you can also use the dirtyStateChanged
event to get notified of a change in the dirty state.storagePrefix
is retrieved.template
is specified, then the data retrieved from the storage is patched with the template and the resulting data structure is immediately saved to the storage. This provide a basic method to evolve the structure of the model and pre-populate it with any defaults.getTemplateData()
: retrieve the template passed to the constructor.resetToTemplate()
: repopulates the model with the template. Any data stored in the model will be lost.updateDataFromTemplate(data, template)
: utility method that is used to patch the data
argument with the template
argument. It returns a object that represents the merge of the data
argument and the template
argument.LocalStorageJSONModel
provides these events:dirtyStateChange
: this event has two parameters, isDirty
to indicate whether the model is now dirty and wasDirty
, indicating whether the model was dirty prior to the latest change. shoppingListModel.attachDirtyStateChange(function(event){
this.dirtyStateChanged(event.getParameters());
}, this);
dirtyStateChanged: function(parameters){
var isDirty = parameters.isDirty;
this.byId('saveButton').setEnabled(isDirty);
this.byId('undoButton').setEnabled(isDirty);
},
attachDirtyStateChange(data, handler, listener)
: attach a handler
function to get notifications of a change in the dirty state. If a some change is made that causes a difference between the stored data and the model data, this event is fired and the handler
is called in the scope of the listener
, and gets passed the application specific payload data
.saveToStorage()
explicitly. But there are also use cases where you simply want the storage to always reflect the state of the model, or at least, track it as closely as possible. The persistence of UI state is such a case, and for these scenarios the LocalStorageJSONModel
supports an automatic save feature.bufferedEventHandler
and persist the data to storage some time after the occurrence of the last change event.autoSaveTimeout
property when you instantiate the model. Alternatively, can also get or set the value of the autoSaveTimeout property after model construction by calling the getAutoSaveTimeout() and setAutoSaveTimeout() methods respectively. To disable autosave, simply set the property to a zero or negative value.You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
6 | |
5 | |
5 | |
4 | |
4 | |
4 | |
3 | |
3 | |
3 | |
3 |