Noodl 2.0β版の機能デモをつくってみた(実装編4：シングルページアプリケーション)

# 概要

NoodlのVer2.0β版を使って作成した機能デモとなります。
Noodlでどんなことができるかを把握すること。
それぞれの機能をどう実装するかの参考となることを目的としています。
今回はこれまで作成したコンポーネントを使いながら、１つのアプリケーションとして公開するまでを説明します。

## 目次
機能紹介編
1. [Noodl 2.0β版の機能デモをつくってみた](https://qiita.com/macole/items/7764c0f2dfa5ac5b1d02)

実装編
1. [ビジュアル・インタラクション](https://qiita.com/macole/items/25611f406395e5271f21)
2. [ビジュアル・インタラクション2](https://qiita.com/macole/items/932fb448c69d4494c16c)
3. [ナビゲーションとコンポーネント化](https://qiita.com/macole/items/178746536a2533d394a9)
**4. シングルページアプリケーション　←今回の記事**

## サンプルデモ・サンプルデータの利用
**･ GitHub上の[デモサイト]**(https://macole.github.io/Noodl2_LibDemo/index.html)

**･ GitHub上のサンプルデータと構築手順**

1. [Github](https://github.com/macole/Noodl)から/Noodl2_libDemo以下を対象PCにCloneしてください。
1. Noodl2を起動しProjects>Import exsisting projectからNoodl2_libDemoを選択してください。
1. LibraryからMaterial UI KitをAddしてください。

**注意事項**
･ このデモはVer2.0β版で作成しています。Ver1.3では動作しません。

---
## 1. ユーザインターフェースの配置
これまで作成してきたコンポーネントを画面上に配置していきます。ここではアプリケーションのUI部分を配置します。

**図 画面上に作成するナビゲーション配置イメージ**
![image403.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192442/ec56e2d2-7966-d892-d500-c400ba2cff5f.png)

### 1-1. 使用するノード

|ノード|説明|
|:-:|:--|
|MuiTheme|ページ全体のデザイン。テーマカラーを一括で設定する|
|Group|ページのルートとして使用|
|02_Header|ページヘッダを表示するための自作コンポーネント|
|MuiButtonNavigation|ページナビゲーション用ノード。※プレビューとDepolyしたファイルで表示が異なるなど使い方に癖がある[^1]|
|MuiButtonNavigationAction|ナビゲーションのアイテムノード|
|MuiIcon|2つ以上の色をブレンドするノード|
|String Selector|インデックスに対応する文字列を出力する|

[^1]: 画面下部に配置するため、ページコンテンツの下に配置しても奥行きが上手く反映されないことや、コンポーネントコンポーネント化するとナビゲーション部分が正しく表示されないなど

### 1-2. ノードの配置・接続
まずはルートとなるGroupを作成し、ナビゲーション部分を子ノードとして配置していきます。
また、ページ全体のデザインを統一するためルートのGroupにMuiThemeを親ノードとして配置します。MuiTheme:Other:typeの設定で｢Dark｣となっていると、ページ全体がダーク基調となります。
ノード接続ではMuiBottonNavigationで選択されている子ノードをTabIndexから取得し、StringSelector:Indexに入力することで、表示されているページのタイトルをヘッダー部分に表示させていてます。

**図 ノード全体**
![image207.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192442/fc183aa8-e0b0-29d1-8aef-5a3899cb73e8.png)

>**MuiButtonNavigationはコンポーネントにするとうまく表示がされません。そのため、コンポーネント化せずページのルートにMuiButtonNavigationノードを配置させています。**

## 2. ページの作成
コンポーネントを配置してページを作成します。ページ自体もコンポーネントとして登録しています。

### 2-1. 使用するノード
|ノード|説明|
|:-:|:--|
|Group|ノードをグループ化するためのノード|
|Text|テキストを表すノード|
|12_MuiCard|Card型コンテンツを表示するための自作のノード|
|ComponentInputs|コンポーネントへの外部入力。Mountedで画面の表示切替を行っている|

### 2-2. ノードの配置・接続
![img0000_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192442/1ec39322-8cf0-76c0-0c76-119445e229f5.png)
作成したページはコンポーネントとして登録し、外部からの表示/非表示入力を受取ります。具体的には`ComponentInputs:Mounted⇒Group:Mounted`と接続することで、GroupのMounted表示/非表示を外部からコントロールできるようにしています。

### 2-3. ページのスクロール
ページのスクロールはGroupノードのScroll Behaviorで設定します。
・None:スクロールしない、Native:スクロールバー、Noodl：スクロールバーのないスクロール

スクロールの方法はScroll Directionで設定します。
・縦スクロール:Vertical、・横スクロール:Horizontal

## 3. 画面遷移
画面遷移の実装は表示したいすべてのページコンテンツを読込み。ページコンテンツの表示/非表示(Mounted)で画面遷移を素早く行います。

1. 画面に表示したいすべての要素Componentを読込む。
2. ユーザインターフェースを使って各Componentの表示/非表示(Mounted)を切替える。

**図 画面遷移のイメージ**
![image404.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192442/d5edc80a-fc8d-9de4-c0b3-fedcf0c86954.png)

作成したページはコンポーネントとして登録し、外部からの表示/非表示入力を受取ります。具体的には`ComponentInputs:Mounted⇒Group:Mounted`と接続することで、GroupのMounted表示/非表示を外部からコントロールできるようにしています。


### 3-1. 使用するノード

|ノード|説明|
|:-:|:--|
|Group|ノードをグループ化するためのノード|
|MuiButtonNavigationAction|ナビゲーションアイテムの自作ノード|
|Expression|単純な式を用いて独自の計算を行う。ここでは｢===｣式を使ってtabの値を判定しています|

### 3-2. ノードの配置・接続
**図 ノード全体**
![img0000_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192442/694e4ca7-912c-d253-2978-4b79a70b7a39.png)
ノード接続のポイントはMuiButotnNavigation:TabIndexで取得したIndex値を各Expression式に入力することと。
Expressionでtabの値を判定し、その結果ResultをページコンテンツのMountedに入力することです。
これによって、選択されたNavigationButtonに応じてページコンテンツの表示/非表示を切り替えています。

## 4. デプロイ・成果物
Noodlは成果物SPA(シングルページアプリケーション)[^2]として、HTMLとJavaScriptファイルを出力します。

[^2]: 一度のダウンロードで、複数のページ要素を持つ構成として実装する手法。ページ遷移が素早くユーザーにダウンロード待ちをさせることなく利用できるため、UI/UX改善に効力がある。

**図 デプロイの方法と成果物**
![image203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192442/a8866164-5e90-810a-f7cc-d4f5aed46ed1.png)
デプロイは画面右上に並んだアイコンの上矢印を選択し、Pick Folderで出力先フォルダを選択することで実行できます。
デプロイ後は先ほど選択したフォルダに下記のファイル群が作成されます。

![image205.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192442/26c17670-059a-494e-ac86-a29407e89643.png)

**図 成果物の配置**
出力されたフォルダをすべてWebサーバにコピーすれば、外部から作成したアプリを使用できます。アクセス先はindex.htmlとなります。
また、CordovaなどWebアプリを開発できるフレームワークを利用することでクロスプラットフォーム対応のアプリにすることができるようです。公式サイトの[Noodlガイド](https://noodl-jp.tds-g.biz/doc/guide/deploying-noodl-projects/)にて解説されています。

---
# まとめ
実装編として今回はこれまで作成したコンポーネントを組みあわせてアプリケーション化までを解説しました。
NoodlではさらにMQTTやWeb APIのよる外部にある実データを利用することができたり。JavaScriptを取込んで機能を追加していくこともできます。

---
# 参考文献

公式
-  [Noodl公式](https://tensorx.co.jp/noodl-jp/)
-  [Noodl ドキュメント](https://noodl-jp.tds-g.biz/doc/)

Noodl2関連のドキュメント
- [Qiita: Noodl 2.0ベータ版に参加しよう！](https://qiita.com/noodl-tokyo/items/e8d9e945c60433019026)
- [Qiita:Noodl 2.0β版が公開されたので使ってみた！ ～チュートリアル～](https://qiita.com/kmaepu/items/fcde6b82f49168a88612)>コンポーネントの追加
- [Qiita:Noodlとmicro:bitをつないで、メッセージのやり取りをする](https://qiita.com/kisaichi07/items/81211926c8ae81a5cd87)>micro:bitとの連携
- [Qiita:Noodlとobnizを使って体重計を簡単に作ってみる](https://qiita.com/iizuka2019/items/2430b71e6654b4724cdb)>obnizとの通信
- [Qiita:NoodlでWeb Speech API Speech Recognitionを使う！Noodl Javascriptノードの使い方も解説](https://qiita.com/kisaichi07/items/5fcf89147b06560d9043)>非同期通信、Web APIとの通信

Noodl関連の動画
- [YouTube:Noodl](https://www.youtube.com/watch?v=e3ZqOCh9_uk&list=PLeaoc1gGIJDyGQF32Z-Ftltxs58rY8Ddk)
- [YouTube:技術書展応援祭清水さんをテーマにした麺書の紹介とか](https://www.youtube.com/watch?v=3oWsPLzMpso)