Help us understand the problem. What is going on with this article?

【Fiori】Dynamic Page, Semantic Page, Object Pageを比較する

目的

Fioriで1ページの画面を作るときに使う代表的な3つのレイアウトを実装し、実装の手間やわかりやすさなどを比較してみます。
関連記事:【Fiori】2つの基本的なレイアウトについて

紹介するレイアウト

  • Dynamic Page
  • Semantic Page
  • Object Page

3つのレイアウトの構成

SAPUI5 version: 1.73.1のAPI Referenceをもとに、それぞれのレイアウトがどのようなaggregation(パーツ)から構成されているかを図に表しました。全てのaggregationではなく、代表的と思われるものだけ載せています。

image.png

Dynamic Page

ヘッダー、コンテンツ、フッターから構成される基本のレイアウトです。
image.png

Semantic Page

aggregationの種類が多く、36種類もあります。aggregationによって画面のどこに表示されるかが自動的に決まります。たとえばDelete、Copyなどのボタンごとにaggregationが用意されており、DeleteはCopyより左に来ることも決まっています。
image.png

Object Page

ヘッダ部分はDynamic Pageと同じですが、コンテンツにあたるsectionが入れ子の構造になっています。ObjectPageSectionが一番外側で、この単位でアンカーバーと呼ばれるタブのようなものがつきます。
image.png

ObjectPageSectionと画面の対応は以下のようになります。
image.png

実装してみた

比較のため、同じ画面パーツ(フラグメント)を使って3つの画面を実装してみました。
ソースは以下にあります。
https://github.com/miyasuta/LayoutSample

image.png

ビューの実装

Dynamic Page

image.png

DynamicPage.xml
<mvc:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
    xmlns:f="sap.f"
    xmlns:l="sap.ui.layout"
    controllerName="demo.Train_20_LayoutSample.controller.DynamicPage" xmlns:html="http://www.w3.org/1999/xhtml">

    <f:DynamicPage id="dynamicPage" headerExpanded="true" showFooter="true">
        <f:title>
            <f:DynamicPageTitle>
                <f:heading>
                    <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.Heading" type="XML" />
                </f:heading>
                <f:content>
                    <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.TitleContent" type="XML" />
                </f:content>
                <f:actions>
                    <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.Actions" type="XML" />
                </f:actions>
                <f:breadcrumbs>
                    <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.Breadcrumbs" type="XML" />
                </f:breadcrumbs>
                <f:navigationActions>
                    <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.NavigationActions" type="XML" />               
                </f:navigationActions>              
            </f:DynamicPageTitle>
        </f:title>

        <f:header>
            <f:DynamicPageHeader pinnable="true">
                <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.HeaderContent" type="XML" />
            </f:DynamicPageHeader>
        </f:header>

        <f:content>
            <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.MainContent" type="XML" />
        </f:content>

        <f:footer>
            <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.FooterActions" type="XML" />
        </f:footer>
    </f:DynamicPage>

</mvc:View>

Semantic Page

image.png

SemanticPage.xml
<mvc:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
    xmlns:l="sap.ui.layout"
    xmlns:semantic="sap.f.semantic"
    controllerName="demo.Train_20_LayoutSample.controller.SemanticPage" xmlns:html="http://www.w3.org/1999/xhtml">

    <semantic:SemanticPage id="semanticPage" headerPinnable="true" showFooter="true">
        <semantic:titleHeading>
            <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.Heading" type="XML" />
        </semantic:titleHeading>

        <semantic:titleContent>
            <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.TitleContent" type="XML" />
        </semantic:titleContent>

        <semantic:headerContent>
            <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.HeaderContent" type="XML" />
        </semantic:headerContent>

        <semantic:content>
            <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.MainContent" type="XML" />
        </semantic:content>

        <semantic:titleBreadcrumbs>
            <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.Breadcrumbs" type="XML" />
        </semantic:titleBreadcrumbs>

        <!--Header actions-->
        <semantic:titleMainAction>
            <semantic:TitleMainAction text="Edit"/>
        </semantic:titleMainAction>

        <semantic:titleCustomTextActions>
            <Button text="Toggle Footer" press="onToggleFooter" />
        </semantic:titleCustomTextActions>

        <semantic:copyAction>
            <semantic:CopyAction />
        </semantic:copyAction>

        <semantic:deleteAction>
            <semantic:DeleteAction />
        </semantic:deleteAction>

        <!--Navigation actions-->
        <semantic:fullScreenAction>
            <semantic:FullScreenAction press="onFullScreen" visible="{= ${/actionButtonsInfo/midColumn/fullScreen} !== null }"/>
        </semantic:fullScreenAction>

        <semantic:exitFullScreenAction>
            <semantic:ExitFullScreenAction press="onExitFullScreen" visible="{= ${/actionButtonsInfo/midColumn/exitFullScreen} !== null }" />
        </semantic:exitFullScreenAction>

        <semantic:closeAction>
            <semantic:CloseAction press="onClose" visible="{= ${/actionButtonsInfo/midColumn/closeColumn} !== null }" />
        </semantic:closeAction>     

        <!--Footer actions-->
        <semantic:messagesIndicator>
            <semantic:MessagesIndicator press="onMessagesButtonPress"/>
        </semantic:messagesIndicator>

        <semantic:positiveAction>
            <semantic:PositiveAction />
        </semantic:positiveAction>

        <semantic:negativeAction>
            <semantic:NegativeAction />
        </semantic:negativeAction>      

        <semantic:footerCustomActions>
        </semantic:footerCustomActions>

    </semantic:SemanticPage>

</mvc:View>

Object Page

image.png

ObjectPage.xml
<mvc:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
    xmlns:l="sap.ui.layout"
    xmlns:uxap="sap.uxap"
    controllerName="demo.Train_20_LayoutSample.controller.ObjectPage" xmlns:html="http://www.w3.org/1999/xhtml">

    <uxap:ObjectPageLayout id="objectPage" showFooter="true">
        <uxap:headerTitle>
            <uxap:ObjectPageDynamicHeaderTitle>
                <uxap:heading>
                    <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.Heading" type="XML" />
                </uxap:heading>
                <uxap:content>
                    <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.TitleContent" type="XML" />
                </uxap:content>
                <uxap:actions>
                    <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.Actions" type="XML" />
                </uxap:actions>
                <uxap:breadcrumbs>
                    <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.Breadcrumbs" type="XML" />
                </uxap:breadcrumbs>
                <uxap:navigationActions>
                    <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.NavigationActions" type="XML" />
                </uxap:navigationActions>               
            </uxap:ObjectPageDynamicHeaderTitle>

        </uxap:headerTitle>

        <uxap:headerContent>
            <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.HeaderContent" type="XML" />
        </uxap:headerContent>

        <uxap:sections>
            <uxap:ObjectPageSection title="Product">
                <uxap:subSections>
                    <uxap:ObjectPageSubSection title="">
                        <uxap:blocks>
                            <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.Product" type="XML" />
                        </uxap:blocks>
                    </uxap:ObjectPageSubSection>
                </uxap:subSections>
            </uxap:ObjectPageSection>

            <uxap:ObjectPageSection title="Customer">
                <uxap:subSections>
                    <uxap:ObjectPageSubSection title="">
                        <uxap:blocks>
                            <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.Customer" type="XML" />
                        </uxap:blocks>
                    </uxap:ObjectPageSubSection>
                </uxap:subSections>
            </uxap:ObjectPageSection>           
        </uxap:sections>

        <uxap:footer>
            <core:Fragment fragmentName="demo.Train_20_LayoutSample.fragment.FooterActions" type="XML" />
        </uxap:footer>

    </uxap:ObjectPageLayout>

</mvc:View>

同じ画面を作るのに要した行数

XMLビューの行数(スペースを除く)をカウントしてみました。

結果

  • Dynamic Page: 40行
  • Semantic Page: 69行
  • Object Page: 58行

Semantic Pageは表示する項目ごとにaggregationが分かれるので、必然的に行数が多くなります。

まとめ

実装してみて感じた各レイアウトのメリット、デメリットは以下です。

レイアウト メリット デメリット、留意点
Dynamic Page シンプルで実装しやすい。項目の配置の自由度が高い ボタンの配置などについてプロジェクトで統一したルールを作ることが必要
Semantic Page 出力位置が自動的に決まるので、一貫したレイアウトになる 多数あるaggregationを使い分ける必要がある。ビューをぱっと見たときにどのような画面になるのか想像しにくい
Object Page コンテンツをグループ化してセクションを作れるので、多数の項目を出す画面に向いている Dynamic Pageと同様
tami
SAPUI5、 Fioriについて学びつつ、アウトプットしていきたいと思います。記事の内容について質問・コメント歓迎です
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした