Alloy Modelの学習・その3(Properties Adapter)
引き続き、Alloy Modelを深ぼってます。
標準で用意されているSync Adapterには、SQLite用のSQL Adapterの他に、Titanium.App.Propertiesを使うProperties Adapterがあります。
※以前はもう一つ、Mobile Web用にlocalStorage adapterというのがあったようですが、Alloy 1.5.0で非推奨になってしまったようです。
Alloy Model、特にData Bindingを使う場面としては、SQLiteとの組み合わせで使うことの方が多い気がしますが、アプリのちょっとした設定を保持しておくのにTitanium.App.Propertiesを使うこともあるので、せっかくなので試しておくことにしました。
今回作るもの
設定画面で使う用途を想定して、1画面にいくつか入力項目があるもの、ということで、単純に名前・性別・国籍を登録しておく画面という、あまり実用性のないものになりました。
すべてテキスト入力だとつまらないので、性別だけOptionDialogを使って選択式にしています。
ソースは umi-uyura/AlloyModelStudyProps にあがっているものです。
プロジェクト作成
例によってCLIでプロジェクト作成。
$ titanium create --type app --id com.example.titanium.alloymodelstudyprops --name AlloyModelStudyProps --platforms iphone,android --url http://www.example.com --workspace-dir . $ alloy new AlloyModelStudyProps
これをベースに、今回もUIはJade & Stylusに、FokkeZB/UTiL/xp.ui を使っています。
モデル作成
上記の画面通り、以下のようなテーブルにします。
内容 | カラム | 型 |
---|---|---|
ID | id | String |
名前 | name | String |
性別 | gender | String |
国籍 | nationality | String |
これをもとに alloy generate
コマンドを使ってモデルを生成。
$ alloy generate model settings properties id:string name:string gender:integer nationality:string
今回想定している設定画面の場合は複数レコードが発生することはないため、レコードを識別する id
は不要な気がしますが、Data Binding(というよりはBackbone?)の仕組み上、キーとなる属性が必要なようです。キーとなる属性がない場合、設定を更新しようとしたときに該当レコードが見つけられず、新しいレコードが作られてしまいます。
生成されたモデルを、最終的に以下のようにしました。
app/models/settings.js
exports.definition = { config: { columns: { "id": "string", "name": "string", "gender": "string", "nationality": "string" }, defaults: { "id": "settingsId", "name": "", "gender": "", "nationality": "" }, adapter: { type: "properties", collection_name: "settings", idAttribute: "id" } }, extendModel: function(Model) { _.extend(Model.prototype, { // extended functions and properties go here }); return Model; }, extendCollection: function(Collection) { _.extend(Collection.prototype, { // extended functions and properties go here // For Backbone v1.1.2, uncomment the following to override the // fetch method to account for a breaking change in Backbone. /* fetch: function(options) { options = options ? _.clone(options) : {}; options.reset = true; return Backbone.Collection.prototype.fetch.call(this, options); } */ }); return Collection; } };
加えたのは config.defaults
で、特に id
には何か初期値を入れておかないと(つまりあらかじめキーを登録しておく)、先ほど述べたレコードが見つからない状態となってしまうようです。
画面とData Binding
今回もスタイルはソースを参照してもらうとして、Viewの index.jade は以下のようにしました。
app/views/index.jade
Alloy Model(src="settings")/ NavigationWindow(module="xp.ui") Window.container(title="Alloy Model Study: Properties", onOpen="doOpen") View.line Label.label Name: TextField#textName.textfield(value="{settings.name}") View.line Label.label Gender: TextField#textGender.textfield(value="{settings.gender}", onClick="doGenderClick") View.line Label.label Nationality: TextField#textNationality.textfield(value="{settings.nationality}") View.controll Button#saveButton(onClick="doSaveClick") Save
前回のData Bindingと少し異なるのは、設定情報は1レコードでCollectionは不要なため、 <Alloy>
タグ直下に記述するBindingする対象に関して、 <Model>
タグで指定してみました。
各TextFieldにData Bindingする項目を設定し、これをもとにコントローラ側も実装。
app/controllers/index.js
var settings = Alloy.Models.settings; function doOpen() { settings.fetch(); } function doSaveClick(e) { var name = $.textName.getValue(); var gender = $.textGender.getValue(); var nationality = $.textNationality.getValue(); settings.save({ name: name, gender: gender, nationality: nationality }); } ...
Viewの open
イベントで Model.fetch()
してデータを読み込み、画面に配置したSaveボタンのクリック時に Model.save()
してデータを保存しています。
Modelオブジェクト単独を扱っているため、Collectionから該当レコードを検索する処理がないこともあり、簡潔に書くことができました。
Appcelerator Titanium Smartphone App Development Cookbook - Second Edition
- 作者: Jason Kneen
- 出版社/メーカー: Packt Publishing
- 発売日: 2015/11/30
- メディア: Kindle版
- この商品を含むブログを見る