ThingWorx 画面部品を再利用する二つの方法

#はじめに

**対象読者**
この記事は、ThingWorx のマッシュアップ開発に関する基礎的な知識を持っている人を対象に書かれています。

**対象バージョン**
ThingWorx 6.4 以降を対象としてます。

#画面部品を再利用する二つの方法

ThingWorx でマッシュアップを作るとき、同じような画面部品をたくさん並べたくなることがよくあります。具体例的な例として、次のスクリーンショットを見てください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/bbe6069c-62f5-fcb8-443b-894d4a1f58ad.png)

表示されている値の詳細はさておき、画面自体は大きく分けて6つのパーツに分かれています。それぞれのパーツにはゲージウィジェットがひとつと、LED ディスプレイウィジェットがみっつほど含まれていますね。

この画面を作るには、6つのゲーウィジェットと18個の LED ディスプレイウィジェットを使えばいいのですが、**それぞれのウィジェットを個別にマッシュアップにドロップすると、表示場所の微調整が大変な作業になります。**

上記スクリーンショットのような、**同じ部品配置を持つパターンを何度も繰り返す**画面構成が必要な場合には、画面部品を再利用できます。

画面部品の再利用方法には大きく分けてふたつのアプローチがありますので、それぞれ概略を説明します。

#パネルウィジェットでグループ化する

パターンとして繰り返すウィジェットを、パネルウィジェットの中に入れてしまう方法です。マッシュアップビルダーはウィジェットのカット・アンド・ペースト操作を通してウィジェットを複製できますが、複製するウィジェットがコンテナー（内部に他のウィジェットを保持できるウィジェット）の場合には、内包物も含めて複製されます。

具体的な手順を見ていきましょう。

##ベースとなるパネルを作る

まず、マッシュアップにベースとなるパネルをひとつ設置します。そしてそのパネルの中に、必要なウィジェットを配置します。
マッシュアップビルダーのレイアウトエリアとエクスプローラー画面のスクリーンショットでは下の画像のようになりますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/491f23e4-cd1a-67b6-af86-6d67f7ba4a93.png)

エクスプローラ上で、"MashUP" の中に "panel-2" が配置され、さらに "panel-2" の中に "gauge-3" や "leddisplay-4"、"leddisplay-5"、"leddisplay-6" のみっつの LED ディスプレイウィジェットが配置されているのが分かります。

##ベースパネルを複製する

ベースとなるパネルができたら、あとは必要な数だけ複製するだけです。

マッシュアップビルダーのレイアウトエリア上部にあるツールバーから、ウィジェットを「コピー」・「ペースト」します。「コピー」アイコンをクリックするとエクスプローラー上で選択されているウィジェットがクリップボードにコピーされ、「ペースト」アイコンをクリックするとクリップボードにコピーされたウィジェットが**選択中の**コンテナウィジェットへ複製されます。「**選択中の**」と強調している理由は、コピーとペーストを同一のコンテナーに対して行なった場合には操作がキャンセルされるためです。上の画像の例では、panel-2 をコピーしたのち、（クリップボードには panel-2 が保存される）、panel-2 自身を panel-2 に対して複製することはできません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/bcfc62da-7a40-bab6-18b6-d5686ed4d977.png)

エクスプローラ上で "panel-2" が選択されていることを確認した後、ツールバーのコピーアイコンをクリックして panel-2 をコピーします。

その後、エクスプローラ上で "Mashup" を選択し直し、ペーストボタンをクリックしてください。そうすると、次のような画面になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/81dce3cb-b77a-bda2-9aab-e34158e46974.png)

##複製されたパネルを移動させる

無事 "panel-32" が作成され、"Mashup" に追加されていることがわかります。ここで少々注意が必要です。ペーストが終わった時点では、コンテナ（ここでは panel-32）に含まれるすべてのウィジェットが選択状態になっています。この状態で "panel-32" を移動させようとしてもうまくいきません。"panel-32" の位置を移動させるには、いったん "Mashup" など別のウィジェットを選択して、あらためて "panel-32 だけを選択しなおします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/aa2774f4-f86b-fd31-d1a1-b9f14562ebde.png)

"panel-32" の移動ができたら、あとは必要な数だけこの操作を繰り返します。

##注意点

この方法はとても簡単で、筆者もよく使うテクニックです。テクニックというほどでもありませんね...
注意点として下記を挙げておきます。

- それぞれのパネルに含まれるウィジェットは完全に独立しているため、マスターとスレーブのような関係にはありません。このため、コピー元となった "panel-2" を変更しても、コピーされた "panel-32" のような他のパネル内部のウィジェットには一切影響を与えません。統一した意匠を持たせたい場合、変更作業はすべてのパネルに対して行う必要があります。ちょっと手間かもしれませんね。
- コピー・アンド・ペースト操作は取り消せません。手元が狂って「コピーするつもりがカットしちゃった」というのは筆者もときおりやってしまうのですが、一旦カットしたものはもういちどペースト操作でウィジェットに貼り付けたとしても、元あった場所ではなく上位のコンテナーウィジェットの左上に配置されてしまいます。こまめに保存しながら、間違ったときには編集をキャンセルするかどうか、焦らずじっくり考えましょう...

#マッシュアップを部品化する

マッシュアップを部品化する、などというと、たいそうなテクニックを駆使するようなイメージがありますが、そんなことはありません。ThingWorx ではレイアウトエリアにウィジェットを配置していくことで画面を開発していきますが、実はレイアウトエリアにはウィジェットだけではなく、マッシュアップも配置できます。大事なことは二度書きましょう。マッシュアップには、他のマッシュアップを部品として配置できます。

先ほどの手順でベースとなるパネルを作成しました。今度はベースとなるパネルではなく、ベースとなるマッシュアップを作ることから始めます。

##ベースマッシュアップを作る

コンポーザーで新しいマッシュアップを作成してください。レスポンシブでも固定サイズでも構いませんが、慣れないうちは固定サイズから始めるのをお勧めします。

新しいマッシュアップを作成したら、必要となるウィジェットをすべて配置します。次のスクリーンショットのようになりますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/7e84abc6-a72e-bac7-990b-0d2c994c7c3c.png)

ここまでの手順は、「パネルウィジェットでグループ化する」手順と大きな差はありません。

##マッシュアップパラメータを設定する

つぎに、このマッシュアップ（部品化されたマッシュアップ）が、親となるマッシュアップから値を受け取るための「パラメータ」をセットします。ここでセットするパラメータを通じて、マッシュアップ間でデータをやり取りすることになります。

エクスプローラでマッシュアップ（"Mashup"）が選択されていることを確認して、レイアウトウィジェットのマッシュアップ領域の左上にある、下向き三角にマウスを合わせます。（ロールオーバさせます）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/7815ca20-0d6c-6719-84b4-929477d51bcb.png)

そうすると、マッシュアップに対するコンテクストメニューが表示されますので、"Configure Mashup Parameters" をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/b3dc1c1b-042d-5f22-6a9e-a489211b1d63.png)

"Configure Mashup Parameters" という名前のウィンドウが新たに開きますので、上部にある "Add Parameter" という黒いボタンをクリックして、パラメータを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/2ebcff6e-ea98-7832-7770-d92ef1cbf073.png)

"name" にはパラメータの名前を、"Base Type" にはデータ型を、そして "Binding Direction" にはパラメータの受け渡し方向を指定します。親マッシュアップから値を受け取る際には、"Binding Direction" は右向きの矢印にしておきます。

必要な数のパラメータを定義したら、右下にある緑の "Done" ボタンをクリックして編集を確定させます。

**この時点で、いったん "Save" ボタンをクリックして、マッシュアップの編集を ThingWorx サーバー側で確定させてください。そうしないと、以降の手順が正しく実施できません。**

##マッシュアップパラメータをウィジェットにバインドする

通常、ウィジェットには Thing のプロパティなどをバインドします。このとき、ウィジェットに対してバインドされている Thing のプロパティのことを「バインドソース」と呼んでいます。日本語だと「結びつけの元」ですね。バインドソースは、Thing のプロパティやサービスの戻り値の他、上記で作成したマッシュアップパラメータを指定できます。

エクスプローラで "Mashup" が選択されていることを確認して、レイアウトエリアのマッシュアップ領域左上にある下向き三角にマウスを合わせます。そうすると...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/9c4dfc0f-49bf-5b16-ae5d-658c87ec2e9c.png)

先ほど追加したマッシュアップパラメータが表示されていることが確認できますね。もしも追加したマッシュアップパラメータが表示されていない場合には、"Save" ボタンをクリックしたのち、一旦 "panel-2" などを別のものを選択して、もう一度 "Mashup" に選択を戻します。

あとは、通常のバインド作業のように、（マッシュアップ）パラメータをウィジェットにバインドさせます。バインド後のリレーションウィンドウは下記のように表示されていると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/3e1c20cd-7aa2-7a4b-8fab-a7f084071f1a.png)

##親マッシュアップを作る

ここまでの手順で、「部品として使うマッシュアップ」の作成が終わりました。いよいよマッシュアップを部品として使ってみましょう。

新しくマッシュアップを一つ作ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/20c25947-7fd7-4c8c-1904-5f8ab22a0c7f.png)

マッシュアップビルダーの左側、通常はウィジェット一覧などが表示されている部分で "Mashups" を選択し、先ほど作った「部品として使うマッシュアップ」を選択します。検索ボックスがありますので、必要な場合にはマッシュアップ名などを入力するとマッシュアップが絞り込めます。

部品として使うマッシュアップが特手できたら、ウィジェットと同じようにマッシュアップをレイアウトエリアにドロップして配置します。**注意点として、部品としてドロップするマッシュアップが固定サイズの場合には、親のマッシュアップ側でサイズを指定する必要があります。親のマッシュアップに部品マッシュアップを配置した際には、"mashupcontainer-2" のようなウィジェットとして見えますので、"mashupcontainer-2" の縦横サイズを、部品マッシュアップで指定されているサイズと同じにします。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/27ca6cc5-c74b-6284-aa2b-80e2da985fb0.png)

必要なぶんだけ、マッシュアップを画面に配置します。配置されたマッシュアップもウィジェット同様、ツールバーの「カット」・「コピー」・「ペースト」操作を受け付けますので、活用してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/ea292a2e-f474-2b6c-89b1-d43969279789.png)

画面に配置されたマッシュアップは、通常のウィジェットと同じようにデータをバインドできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/54b4a0df-b8d8-3ffa-7a11-baff9f266b38.png)


バインド完了後には、リレーションエリアの表示は下記のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119047/dfcafb8d-19ca-1dde-82fe-51b14904e26f.png)

##注意点

マッシュアップの部品化では、マッシュアップ間のデータの受け渡しをマッシュアップパラメータを通して行います。実際の Thing のプロパティやサービスの戻り値に対して直接バインドしないため、抽象度が上がり、再利用性が高くなります。

注意点としては、

- ベースとなるマッシュアップとコピーされたマッシュアップの関係はマスターとスレーブになります。ベースとなるマッシュアップに対する変更は、親マッシュアップに配置されているすべてのマッシュアップに適用されます。このため、「個別に微妙に意匠を変えたい」場合には、マッシュアップによる部品化は適しません。この場合は、この記事の最初の方の例である「パネルでグループ化する」アプローチを推奨します。
- リスト・ウィジェットやグリッド・ウィジェットの選択状態は、マッシュアップを超えて通知されません。マッシュアップパラメタもしくはセッションパラメタ経由で選択状態の変化を受け渡す必要があります。

#比較

以上、パネルを用いてウィジェットをグループ化する方法と、マッシュアップを部品化するほうほうの二つをみてきました。どちらの方法も劇的に画面作成の時間を減らしてくれますが、どちらの方法がより優れているのでしょうか？

一概にどちらがよりよいとは言えませんが、筆者は次の判断基準で使い分けています。

- 頻繁にいろいろなマッシュアップで利用する画面部品を作る場合は、マッシュアップを使う。
- 他の ThingWorx サーバーでも利用したい場合は、マッシュアップを使う。
- 他のマッシュアップでは使わないけれど、一つのマッシュアップで繰り返し使われる場合はパネルを用いてグループ化する。
- それぞれの部品で、微妙に意匠を変える必要がある場合には（つまり均一な表現では要件が充足できない場合には）パネルを用いてグループ化する。

#落ち穂拾い

ところで、この記事で紹介したウィジェットのコッピー・アンド・ペースト機能ですが、実はマッシュアップを超えて適用できます。つまり、マッシュアップ A に配置されている部品をコピーしてクリップボードに保存した後、マッシュアップ B でペーストすると、きちんとペースト操作が完了します。おなじデータソースをマッシュアップ A もマッシュアップ B も使っている場合には、バインド情報も維持されます。

なお、マッシュアップビルダーの「クリップボード」とは、マッシュアップビルダーが内部的に用意している領域であり、Windows や Mac が持っているクリップボードとは別物ですのでご注意を。

#他のリソース

この記事の最初でマッシュアップのスクリーンショットを紹介しましたが、ゲージウィジェットは少々手を入れています。ゲージウィジェットのカスタマイズ（とはいってもマッシュアップビルダーで設定するだけです）方法は、[こちらの記事](https://qiita.com/kanoloa/items/fe33af811a4762c2344f)をご覧ください。