OnsenUIとNiftyCloudとAnglarJsを組み合わせてみた。(Monaca)

# OnsenUIとNiftyCloudとAnglarJsを組み合わせてみた。 (Monaca)

- 結論から言うと、Model=NiftyCloud,Controller = AnglarJS,View = OnsenUIという構成で作ってみました。
 - 作るものからすると、大半、簡単な画面なので、手軽にやりたかったのが、無学でつっこんだら意外にめんどくさかった :sweat: 
 - OnsenUIだけでは、複数ページでJavaScriptを分割するのが難しい。。どうしても、AnglarJSとの組み合わせになる。（OnsenUIはAnglarJSをベースにしているようなので、他のフレームワークいれるのもなぁ。。）
 - NiftyCloudを使えば、アプリサイドからもサーバーからもSQLが発行可能。Monacaがサポート歌っているし、そのままModelとして使いたい。Restにするのもめんどいし（笑）
 - ちょこちょこどのライブラリも使い方が変わっていた。日付にお気をつけて。

1.ファイル構成は以下のようにした。

```text:tree.txt
├── config.xml
├── platforms
  〜中略〜
└── www
    ├── README.md
    ├── components
    │   ├── loader.css
    │   ├── loader.js
    │   ├── monaca-cordova-loader
    │   │   ├── bower.json
    │   │   └── cordova-loader.js
    │   ├── monaca-core-utils
    │   │   ├── bower.json
    │   │   └── monaca-core-utils.js
    │   └── numb   ★NiftyCloudのライブラリ
    │       ├── LICENSE
    │       ├── README.md
    │       ├── bower.json
    │       └── ncmb.min.js
    ├── css
    │   └── style.css
    ├── img
    │   ├── xxx.png
    ├── index.html
    ├── js
    │   ├── controller
    │   │   └── TestController.js ★今回作るAnglarJSのコントローラ
    │   └── model
    │       ├── base.js　★ 今回作るNiftyCloudのBaseModel
    │       └── test.js　★ 今回作るNiftyCloudのModel
    ├── lib ★ MonacaでOnenUI+angularで作成。
    │   ├── angular
    │   │   ├── angular-animate.js
    │   │   ├── angular-animate.min.js
  〜中略〜
    │   └── onsenui
    │       ├── CHANGELOG.md
  〜中略〜
    └── test.html　★今回作成するファイル。
```

2. Modelを作成する。今回はとりあえず、検索のみ。

```js:base.js
window.APP_KEY = "XXXX1111"; ★NiftyCloudで取得したKey
window.CLIENT_KEY = "XXXXXXXX222";

var ncmb = new NCMB(APP_KEY, CLIENT_KEY);
```

```js:test.js
var TestDataController = {
    init : function() {
        $(function() {
            TestDataController.prepare();
        });
    },
    prepare : function() {
    },
  getTest : function() {
    return new Promise(function(resolve, reject) { ★非同期にするためPromiseで返す。
    var tt = ncmb.DataStore("T_TEST");
    tt.equalTo("type", "001")
             .order("no",true)
             .fetchAll()
             .then(function(results){
                var tests = new Array();
                for (var i = 0; i < results.length; i++) {
                  var object = results[i];
                  tests.push({"val":object.objectId,"test":object.get("test")});
                }
                resolve(tests);　★resolveをする必要がある。
              })
             .catch(function(error){　★catchは必須っぽい。
                relative(error);　★relativeをする必要がある。
              });
            });
          }
};
```

3.Controllerを作成する。

```js:TestController.js
// Testページのコントローラ
module.controller('TestController', function($scope) {

  TestDataController.prepare();
  var pro = TestDataController.getTest();
  // Promise Success!!
  pro.then(function(value) {
    // Scope内のCtrlの変数を上書きする。
    $scope.testCtrl.messages = value; ★コールバックの中なので、ViewでAsでつけた名前で指定する必要がある。
    // scopeの変更を明示的に通知する。 ★非同期の場合は、$html,$timeoutなどでなければ必須。
    $scope.$apply();
  });
  // Promise Error!!　★これも必須っぽい。
  pro.catch(function(error) {
    console.log(error);
  });
});
```

4.Viewを作成する。

```html:index.html
<!DOCTYPE HTML>
<html ng-app="myApp">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <meta http-equiv="Content-Security-Policy" content="default-src * data:; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
    <script src="components/loader.js"></script>
    <script src="lib/angular/angular.min.js"></script>
    <script src="lib/onsenui/js/onsenui.min.js"></script>
    <script src="lib/onsenui/js/angular-onsenui.min.js"></script>
    <script>var module = ons.bootstrap('myApp', ['onsen']);</script>
    <script src="components/ncmb/ncmb.min.js"></script>
    <script src="js/model/base.js"></script>
    <script src="js/model/test.js"></script>
    <script>TestDateController.init();</script>
    <script src="js/controller/TestController.js"></script>
    <link rel="stylesheet" href="components/loader.css">
    <link rel="stylesheet" href="lib/onsenui/css/onsenui.css">
    <link rel="stylesheet" href="lib/onsenui/css/onsen-css-components-cus.css">
    <link rel="stylesheet" href="css/style.css">
    <script>
        module.controller('AppController', function($scope) {
            $scope.load = function(page) {
              $scope.mySplitterContent.load(page) ★ここは使うテンプレート次第。
            }
            $scope.open = function() {
              $scope.mySplitterSide.open();　★ここは使うテンプレート次第。
            }
          });

        ons.ready(function() {
            console.log("Onsen UI is ready!");
        });
    </script>
</head>
<body ng-controller="AppController as app">
★ここは使うテンプレート次第。
</body>
</html>
```

```html:test.html
 <ons-page ng-controller="TestController as testCtrl" id="TestPage">
 <ons-list>
    <ons-list-item>
      <div class="prop-desc">
        <label for="select-native-1">メッセージ</label>
            <select id="ms_status_sel1">
                <option ng-repeat="tc in testCtrl.states" value="{{tc.val}}">{{tc.test}}</option>
            </select>
      </div>
    </ons-list-item>
 </ons-list>
 </ons-page>
```
##### 注意事項
*非同期の場合は、$html,$timeoutを使えと書いているサイトが多いけど、$scope.$apply();使うのが推奨と公式にあった。*
*コールバックの中で、$scope.messages this.messagesとかいても効かないので注意。*
*Promiseパターンの書き方に注意。*