sapui5tutors SAPUI5 • Fiori • SAP BTP Step-by-step tutorials Real project examples Interview Q&A
Practical SAPUI5 • Fiori • SAP BTP tutorials and interview prep

SAPUI5 Data Binding Deep-Dive: One-Way, Two-Way, One-Time

Data binding is the heart of SAPUI5. It wires your controls to your model so the UI updates itself. But binding modes — one-way, two-way, one-time — trip up even experienced developers. Pick the wrong one and you get stale screens or phantom writes. Let's make each mode concrete.

The three modes in 30 seconds

  • One-way: model → control. Changes in the model update the UI. User input does not flow back.
  • Two-way: model ↔ control. Edits in the UI write straight back into the model.
  • One-time: model → control, once. The value is read at bind time and never updated again.

The defaults matter. JSON models default to two-way; OData models default to one-way (one-time for lists). Knowing the defaults saves you from surprises.


One-way: display data

Use one-way for read-only display: table rows, labels, status texts. The UI reflects the model, and nothing the user does can corrupt it.

<ObjectListItem
  title="{orders>OrderName}"
  number="{orders>Amount}"
  type="Active"/>

This is also the safe default when you're not sure. Binding a label two-way is harmless but sloppy — one-way states your intent.


Two-way: forms and editing

Two-way binding is for inputs. The user types, the model updates, and any other control bound to the same path refreshes automatically.

<Input value="{path: 'customer>Name', mode: 'TwoWay'}"/>
<Text text="Hello, {customer>Name}"/>

Type in the input and the greeting text updates live — no controller code at all. That is the magic you're paying for. Just remember: two-way on an OData model queues a real update request, so don't bind editable fields to production data without a save strategy.

Two-way binding turns forms into declarative code. But with OData, every keystroke can mean a backend call — use batch groups or a local JSON edit model, then submit once.


One-time: static, high-volume lists

One-time binding evaluates the expression once and detaches. No change listeners, no overhead. It's the fastest option and perfect for data that never changes after load — say you have a report of last quarter's figures rendered in a thousand-row table.

<ColumnListItem>
  <Text text="{path: 'report>Region', mode: 'OneTime'}"/>
  <ObjectNumber number="{path: 'report>Total', mode: 'OneTime'}"/>
</ColumnListItem>

For large aggregations this can visibly improve rendering time, because the binding layer does zero tracking work.


Changing the mode

Set it per binding as shown above, or set the default for a whole model in code:

const oModel = new JSONModel(data);
oModel.setDefaultBindingMode("OneWay");
this.getView().setModel(oModel);

A common gotcha: a binding that "doesn't update" is often one-time or one-way when you expected two-way. Check the mode first before debugging anything else.

Memorize the defaults (JSON = two-way, OData = one-way) and choose the weakest mode that does the job. Your app will be faster and your data safer.

Ever been bitten by a wrong binding mode? Tell the story in the comments.