You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A nested viewis a view that is built from several independent parts. In abap2UI5 there are two main ways to achieve this: composing a single view tree from helper methods, and splitting the app into sub-apps that each own a slice of the view.
6
+
A **nested view** in abap2UI5 is a separate XML view fragment that you inject into a *placeholder* inside another view. The main view stays on screen; only the nested fragment is rendered (and later re-rendered or refreshed) independently. This is the standard pattern for master-detail screens, side panels, tab content, and anywhere you want one part of the UI to update without rebuilding the whole page.
7
7
8
-
#### Composing with Helper Methods
8
+
If you know SAPUI5's [nested views](https://sapui5.hana.ondemand.com/sdk/#/topic/df8c9c3d6f2a4d728ba7d6f4cb6c6d35) (`<mvc:XMLView viewName="..."/>`), the goal is the same — split the UI into independently managed pieces. In abap2UI5 the wiring is done from ABAP at runtime: instead of referencing a static view file, you build the nested view's XML in ABAP and tell the client to plug it into a named slot.
9
9
10
-
The fluent builder returns each node as an object reference, so you can pass a node into a helper method and let it add children there:
10
+
#### The Basic Pattern
11
+
12
+
Two ingredients are needed:
13
+
14
+
1.**An anchor in the main view** — any control with an `id`. The nested view will be inserted *into* this control.
15
+
2.**A nested view + a `nest_view_display` call** — builds the fragment and ships it to the named anchor.
11
16
12
17
```abap
13
-
METHOD z2ui5_if_app~main.
14
-
IF client->check_on_init( ).
15
-
DATA(xml) = z2ui5_cl_xml_view=>factory( ).
16
-
DATA(page) = xml->shell( )->page( 'My App' ).
18
+
" 1) Main view with an anchor
19
+
DATA(lo_view) = z2ui5_cl_xml_view=>factory( ).
20
+
DATA(page) = lo_view->shell(
21
+
)->page( title = `Main View`
22
+
id = `test` ). " <-- the anchor id
23
+
24
+
page->content(
25
+
)->button( text = `Re-render only the nested view`
method_insert = `addContent` ). " UI5 mutator on that control
45
+
ENDCASE.
46
+
```
17
47
18
-
build_header( page ).
19
-
build_content( page ).
20
-
build_footer( page ).
48
+
What happens at runtime: `view_display` paints the main view; the page with `id="test"` sits on screen. When the user clicks the button, `nest_view_display` ships the nested XML to the client, which calls `addContent( ... )` on the control with that id. The nested fragment appears inside the page — without re-rendering the page itself.
21
49
22
-
client->view_display( xml->stringify( ) ).
23
-
ENDIF.
24
-
ENDMETHOD.
50
+
The full pattern (re-render everything vs. main only vs. nested only) is in `Z2UI5_CL_DEMO_APP_065`.
|`val`| The nested view's XML, produced by `stringify( )`. |
57
+
|`id`| The id of the anchor control in the main view. |
58
+
|`method_insert`| UI5 mutator method called on the anchor to add the nested view (e.g. `addContent`). |
59
+
|`method_destroy`| Optional. UI5 mutator method that removes the previous nested content before inserting the new one. |
60
+
61
+
`method_insert` and `method_destroy` are plain UI5 control methods — pick whichever the anchor exposes. The choice depends on the anchor's aggregation:
62
+
63
+
| Anchor control | Typical `method_insert`| Typical `method_destroy`|
Always pass `method_destroy` when the nested view is going to be replaced over the lifetime of the app; otherwise consecutive calls stack new fragments on top of the old ones.
71
+
72
+
#### Independent Re-rendering
73
+
74
+
The whole point of nested views is to re-render only what changed. Three calls cover the common needs:
|`client->view_display( ... )`| Replaces the main view's XML. The anchor is recreated, so any nested content is lost too. |
79
+
|`client->nest_view_display( ... )`| Replaces only the nested view. The main view stays on screen. |
80
+
|`client->nest_view_model_update( )`| Pushes current ABAP data values into the **already-rendered** nested view. No re-render. |
81
+
82
+
The matching call for the main view is `client->view_model_update( )` — push data changes into the rendered main view without re-rendering it.
83
+
84
+
A rule of thumb:
85
+
86
+
-**Layout changed** (different controls, new columns, new sections) → `view_display` / `nest_view_display`.
87
+
-**Only the data changed** (a flag flipped, a row added to a bound table) → `view_model_update` / `nest_view_model_update`.
88
+
89
+
`Z2UI5_CL_DEMO_APP_065` shows the difference between the three options in a single screen with one button per call.
35
90
36
-
METHOD build_footer.
37
-
io_page->footer( )->button(
38
-
text = 'Save'
39
-
press = client->_event( 'SAVE' ) ).
91
+
#### Master-Detail with `FlexibleColumnLayout`
92
+
93
+
The most common real-world use: a master list on the left, detail content on the right. `sap.f.FlexibleColumnLayout` is the standard container; abap2UI5 nests the detail view into its middle column.
94
+
95
+
```abap
96
+
" Master view — built once
97
+
DATA(page) = z2ui5_cl_xml_view=>factory(
98
+
)->page( title = `abap2UI5 - Master Detail` ).
99
+
100
+
DATA(lr_master) = page->flexible_column_layout(
101
+
layout = client->_bind_edit( mv_layout )
102
+
id = `test` " anchor
103
+
)->begin_column_pages( ).
104
+
105
+
lr_master->list( items = client->_bind_edit( val = t_tab
106
+
view = client->cs_view-main )
107
+
selectionchange = client->_event( `SELCHANGE` )
108
+
)->standard_list_item( title = `{TITLE}`
109
+
selected = `{SELECTED}` ).
110
+
111
+
client->view_display( page->stringify( ) ).
112
+
```
113
+
114
+
When the user picks a row, a detail view is rendered into the middle column:
page->ui_table( rows = client->_bind_edit( val = t_tab2
122
+
view = client->cs_view-nested ) ).
123
+
" ...columns, toolbar, row actions...
124
+
125
+
client->nest_view_display(
126
+
val = lo_view_nested->stringify( )
127
+
id = `test`
128
+
method_insert = `addMidColumnPage`
129
+
method_destroy = `removeAllMidColumnPages` ).
40
130
ENDMETHOD.
41
131
```
42
132
43
-
Each helper receives the parent node by reference and attaches its controls to it. The final `stringify( )`call serialises the entire tree — including all nested children — into one XML string.
133
+
The layout is bound editable (`mv_layout`), so events like *full-screen mode* or *close detail* simply update `mv_layout` and call `view_model_update` / `nest_view_model_update`. The FCL transitions itself; no view is rebuilt.
44
134
45
-
#### Sub-Apps
135
+
End-to-end samples:
46
136
47
-
For larger apps it is useful to split responsibility across separate ABAP classes. Each sub-app implements `z2ui5_if_app` and manages its own piece of the view. The parent app instantiates the sub-app, passes the client, and merges the returned view fragment into its own view tree.
137
+
-`Z2UI5_CL_DEMO_APP_069` — tree master, two interchangeable detail apps (`addMidColumnPage`).
138
+
-`Z2UI5_CL_DEMO_APP_097` — list master, `sap.ui.table.Table` in the detail with sort/filter/row actions.
139
+
-`Z2UI5_CL_DEMO_APP_085` — full master-detail with an `ObjectPageLayout` as the nested detail, including search, sort, and the FCL fullscreen toggle.
48
140
49
-
**Parent app:**
50
-
```abap
51
-
METHOD z2ui5_if_app~main.
52
-
IF client->check_on_init( ).
53
-
sub_app = NEW z2ui5_cl_my_sub_app( ).
54
-
ENDIF.
141
+
#### Routing Bindings to the Right View
55
142
56
-
DATA(xml) = z2ui5_cl_xml_view=>factory( ).
57
-
DATA(page) = xml->shell( )->page( 'Parent' ).
143
+
Each view (main, nested) has its own client-side model. When you build a binding with `client->_bind( ... )` you can declare which view's model the binding belongs to via the `view` parameter:
58
144
59
-
" Let the sub-app render into a container on the page
items = client->_bind_edit( val = t_tab view = client->cs_view-main )
62
148
63
-
client->view_display( xml->stringify( ) ).
64
-
ENDMETHOD.
149
+
" In the nested view
150
+
rows = client->_bind_edit( val = t_tab2 view = client->cs_view-nested )
65
151
```
66
152
67
-
**Sub-app:**
153
+
The constants `client->cs_view-main` and `client->cs_view-nested` are abap2UI5's view identifiers. Declaring them lets `nest_view_model_update( )` know which model to refresh:
154
+
68
155
```abap
69
-
METHOD render.
70
-
io_node->text( 'I am the sub-app' ).
71
-
io_node->button(
72
-
text = 'Sub Action'
73
-
press = io_client->_event( 'SUB_ACTION' ) ).
74
-
ENDMETHOD.
156
+
DELETE t_tab2 WHERE title = ls_arg-title.
157
+
client->nest_view_model_update( ). " only the nested view's data is pushed
75
158
```
76
159
77
-
The sub-app appends its controls to whatever node the parent provides. Events fired inside the sub-app are handled by the sub-app's own `main` method on the next roundtrip.
160
+
If you omit `view`, the binding defaults to the main view, which still works for many cases but is less explicit. Get into the habit of passing the right `cs_view-...` value whenever a fragment is built — it makes the data flow obvious to anyone reading the code.
78
161
79
-
#### Navigation Between Views
162
+
#### Two Levels of Nesting
80
163
81
-
When the nested content changes completely — for example, a detail page replacing a list — use `view_display` to swap the entire view rather than nesting:
164
+
The middle column can itself host another nested view in the end column — useful for master / detail / detail-of-detail flows. abap2UI5 exposes a second method for this level:
Reserve true nesting for content that appears side-by-side or in a stable layout shell. Use `view_display` for sequential navigation where one screen fully replaces another.
180
+
`nest2_view_display` works exactly like `nest_view_display` but targets the second level — typically the FCL's *end* column. `Z2UI5_CL_DEMO_APP_098` walks through all three columns: a list selects a row, a row-action navigates to the end column, the layout switches to `ThreeColumnsEndExpanded`.
| Different visual sections that update at different rates | Nested views — re-render each piece on its own |
187
+
| Master-detail, FCL columns, drill-down navigation | Nested views — the canonical use case |
188
+
| A side panel that toggles open/closed but keeps the page intact | Nested views |
189
+
| Building one view from helper methods (still rendered as one) | Plain ABAP composition — pass nodes between methods, no `nest_view_display` needed |
190
+
| One full screen replacing another |`view_display` with the new view (or `nav_app_call` for a separate app) |
191
+
192
+
Plain composition is the right starting point: keep helper methods that take a parent node and add children to it. Reach for nested views once the UI has clear sub-areas that need to update independently — otherwise you pay for ceremony you don't use.
93
193
94
194
#### Tips
95
195
96
-
- Keep each helper or sub-app focused on one logical section. A helper that grows beyond ~30 lines is a candidate for its own sub-app class.
97
-
- Sub-apps can hold their own instance attributes for local state. Because the whole app tree is reconstructed on every roundtrip, each sub-app re-renders from its current state automatically.
98
-
- Pass only the node the sub-app needs, not the whole view root. This limits the sub-app's scope and makes the boundary explicit.
196
+
- The anchor id must be unique in the main view. The framework calls `byId` on the rendered view to find it; duplicate ids break the lookup.
197
+
- Always provide `method_destroy` when a nested slot will be replaced more than once. Forgetting it causes nested fragments to accumulate.
198
+
- Build the nested view in its own method (e.g. `view_display_detail`) and call it both from the initial render and from event handlers. Two call sites, one definition.
199
+
- If a nested view does not pick up a data change, you probably need `nest_view_model_update( )`; if a control simply isn't there, you need `nest_view_display( )` again.
200
+
- For very large apps, look at `Z2UI5_CL_DEMO_APP_104`, which loads each detail screen from a separate `z2ui5_if_app` class and renders it into the nested slot. It is an advanced pattern — start with the simpler form first.
99
201
100
-
See `Z2UI5_CL_DEMO_APP_160` for an end-to-end example of parent and sub-app composition.
202
+
See `Z2UI5_CL_DEMO_APP_065`, `Z2UI5_CL_DEMO_APP_069`, `Z2UI5_CL_DEMO_APP_085`, `Z2UI5_CL_DEMO_APP_097`, `Z2UI5_CL_DEMO_APP_098`, and `Z2UI5_CL_DEMO_APP_104` for runnable examples covering every variation above.
0 commit comments