だいたい563日前に更新最終更新日時: 2008-08-25 (月) 21:22:36 563日前
現在の位置
Memorycraft Wiki > SproutCoreのモダンなモデル層2
SproutCore?のモダンなモデル層 2
最新のMVCアプローチの利点の一つにモデルオブジェクトの遅延ロードがあります。
SproutCore?はStoreと呼ばれるものを使用して、すぐに使える形で遅延ロードをサポートします。
SC.Store: それって何をするもの?
SC.Storeはアプリケーションにロードされた全てのモデルオブジェクト参照を保持する定義済みオブジェクトです、
そのrecordTypeを気にする必要はありません。なぜならSC.Storeはコントローラーにとって、りっぱな監視対象となるためです。
これにより、そのモデルがどのようにアプリケーションにロードされたかをコントローラーが気にする必要がなくなります。これはとてもよい事です。
それでは実際にこれがどのように動くかを知るために、簡単なSproutCore?アプリケーションを作ってみましょう。
まずは、アプリケーションを生成します。
$ sproutcore sample_app
次にモデルクラスを作ります。
$ cd sample_app $ sc-gen model sample_app/my_record
そして、アプリケーションを実行し、FireBug?で動作を確認します。
$ sc-server
FireFox?(FireBug?はインストール済みとします)を立ち上げて、http://localhost:4020/sample_app にアクセスします。
FireBug?アイコンをクリックしてFireBug?を起動し、コンソールで、以下のように実行します。
>>> SC.Store.records(); [ ]
空の配列が確認できます。
新規にレコードを作成しましょう。
>>> SampleApp.MyRecord.create({ 'name': "Greek God" });
Record({ guid="@1402" }) name=Greek God _bindings=[0] _observers=[0]
>>> SC.Store.records();
[ ]
うーん、予想と違いますね。代わりにこうしてみましょう。
>>> SC.Store.addRecord( SampleApp.MyRecord.create({ 'name': "Greek God" }) );
>>> SC.Store.records();
[Record({ guid="@2455" }) name=Greek God _bindings=[0] _observers=[0]]
うまくいきました!つまり表示されるためには、新規に作成したレコードをStoreに追加してあげる必要があるようです。
SC.Storeの監視
さて、Storeにレコードを追加する方法は先ほど説明しました。次はその方程式にコントローラーを追加してみましょう。
まずコントローラーを生成します。
$ sc-gen controller sample_app/my_records
clients/sample_app/controllers/my_records.js を開き、以下のように変更します。
// ==========================================================================
// SampleApp.MyRecordsController
// ==========================================================================
require('core');
require('models/my_record');
/** @class
(Document Your View Here)
@extends SC.Object
@author AuthorName
@version 0.1
@static
*/ [#m4da898c]
SampleApp.myRecordsController = SC.CollectionController.create(
/** @scope SampleApp.myRecordsController */ {
// TODO: Add your own code here.
content: SC.Collection.create({ recordType: SampleApp.MyRecord })
}) ;
基本的に、SampleApp?.myRecordsController? は、SampleApp?.MyRecord? 型のレコードのSC.CollectionをコンテンツプロパティとするSC.CollectionController? にしてください。
他のオプションを設定することも出来ますが、デフォルトで十分です。
FireFox?に戻って、反映させるためにページを更新してください。そしてFireBug?を立ち上げて、コンソールに以下のように入力します。
>>> SampleApp.myRecordsController.get('arrangedObjects');
[ ]
これはまだレコードを何も追加していないので、予期したとおりの結果です。
次にこうします。
>>> SC.Store.addRecord( SampleApp.MyRecord.create({ 'name': "Greek God" }) );
>>> SampleApp.myRecordsController.get('arrangedObjects');
[ ]
うーん、これは予想外です。作成したコレクションが コレクションコントローラのコンテンツとして更新されたかを確認してみましょう。
>>> SampleApp.myRecordsController.get('content').get('count');
1
OK、ちょっといい感じです。少なくともコレクションは更新されているようです。SC.CollectionController?はrefresh() (もしくはそれと同等の)メソッドを持っていません、
ですから、contentプロパティとしてコレクションを再セットし、何が起こるかを見てみましょう。
>>> SampleApp.myRecordsController.set('content', SampleApp.myRecordsController.get('content') );
>>> SampleApp.myRecordsController.get('arrangedObjects');
[Record({ guid="@310" }) name=Greek God _bindings=[0] _observers=[0]]
OK !、コレクションコントローラーはコレクションを反映させています.。が、理由はさておき、コレクションが更新されても通知されません。うーん。。。
この問題の解決に深入りする前にコンソールを使ってもう少し作業します。ここまでは1つのオブジェクトしか追加せず、また空の状態からスタートしていました。
一連のオブジェクトを扱う場合、0個や1個というのはどちらも極端な例であって、より多くのオブジェクトで試すことによって、より動作の特性を明らかにできると思います。
コンソールで、以下のように入力します。
>>> SC.Store.addRecord( SampleApp.MyRecord.create({ 'name': "Roman God" }) );
>>> SampleApp.myRecordsController.get('content').get('count');
2
>>> SampleApp.myRecordsController.get('arrangedObjects');
[Record({ guid="@28829" }) name=Roman God _bindings=[0] _observers=[0], Record({ guid="@310" }) name=Greek God _bindings=[0] _observers=[0]]
うわー!予想と違います。今回は期待通りに、arrangedObjects プロパティが自動で更新されました。何が起こっているのでしょうか?このチュートリアルを書いている途中で上記の異常を発見してしまったのですが、とにかくこのやり方をやめることに決めました。ここでの潜在的な問題は、ローディングプロセスのあまりにも早い段階でコレクションコントローラーに対してcontentプロパティをセットしてしまったことです、そのためSproutCore?はその時点では正しくコンテンツプロパティに接続できなかったのです。
解決方法としては、とにかく私たちがやったようにやること(以下で説明します)、そして、コレクションのセットを別の場所でおこなうことです。
以下に変更した点を記します。まず、clients/sample_app/controllers/my_records.js を変更します(無駄なものを削除)
// ==========================================================================
// SampleApp.MyRecordsController
// ==========================================================================
require('core');
/** @class
(Document Your View Here)
@extends SC.Object
@author AuthorName
@version 0.1
@static
*/ [#w7bd8dbf]
SampleApp.myRecordsController = SC.CollectionController.create(
/** @scope SampleApp.myRecordsController */ {
// TODO: Add your own code here.
}) ;
clients/sample_app/models/my_record.js でコレクションを作成します。
// ==========================================================================
// SampleApp.MyRecord
// ==========================================================================
require('core');
/** @class
(Document your class here)
@extends SC.Record
@author AuthorName
@version 0.1
*/ [#le780297]
SampleApp.MyRecord = SC.Record.extend(
/** @scope SampleApp.MyRecord.prototype */ {
// TODO: Add your own code here.
}) ;
SampleApp.MyRecord.allRecords = SC.Collection.create({ recordType: SampleApp.MyRecord });
最後に、clients/sample_app/main.js でコレクションコントローラのコンテントプロパティにコレクションをセットします。
// ==========================================================================
// SampleApp
// ==========================================================================
// This is the function that will start your app running. The default
// implementation will load any fixtures you have created then instantiate
// your controllers and awake the elements on your page.
//
// As you develop your application you will probably want to override this.
// See comments for some pointers on what to do next.
//
function main() {
// Step 1: Load Your Model Data
// The default code here will load the fixtures you have defined.
// Comment out the preload line and add something to refresh from the server
// when you are ready to pull data from your server.
SampleApp.server.preload(SampleApp.FIXTURES) ;
// TODO: refresh() any collections you have created to get their records.
// ex: SampleApp.contacts.refresh() ;
SampleApp.myRecordsController.set('content', SampleApp.MyRecord.allRecords );
// Step 2: Instantiate Your Views
// The default code just activates all the views you have on the page. If
// your app gets any level of complexity, you should just get the views you
// need to show the app in the first place, to speed things up.
SC.page.awake() ;
// Step 3. Set the content property on your primary controller.
// This will make your app come alive!
// TODO: Set the content property on your primary controller
// ex: SampleApp.contactsController.set('content',SampleApp.contacts);
} ;
さぁ、FireFox?であなたのアプリケーションをリロードして、コンソールに以下のように入力してください。
>>> SC.Store.addRecord( SampleApp.MyRecord.create({ 'name': "Greek God" }) );
>>> SampleApp.myRecordsController.get('arrangedObjects');
[Record({ guid="@310" }) name=Greek God _bindings=[0] _observers=[0]]
成功しました!これで「モダンなモデル層2」 を終了します。パート3に続きます。
- 関連ページ
- Memorycraft Wiki561日前
- SproutCore ドキュメント翻訳561日前
- SproutCoreのモダンなモデル層3563日前
- SproutCoreのモダンなモデル層563日前