Sencha TouchのストアをAjaxプロキシで正しくロードする



インラインデータやlocalstorageのストアをロードするときと比べてajax proxy経由でロードするときはコールバック関数を呼び出す必要がある。

# Controller以外の定義

```javascript:AjaxTest.model.Player.js
Ext.define('AjaxTest.model.Player', {
    extend: 'Ext.data.Model',
    
    config: {
        fields: [
            { name: 'name', type: 'string' },
            { name: 'no', type: 'int' },
            { name: 'position', type: 'string' }

        ]
    }
});
```

```javascript:AjaxTest.view.Main.js
Ext.define('AjaxTest.view.Main', {
	extend: 'Ext.Container',
	xtype: 'main',
	config: {
		tpl: Ext.create('Ext.XTemplate',
			'<tpl>',
				'<p>{name}</p>',
			'</tpl>'
		),
	}
})
```

```javascript:AjaxTest.store.Players.js
Ext.define('AjaxTest.store.Players', {
	extend: 'Ext.data.Store',
	xtype: 'players',
	config: {
		model: 'AjaxTest.model.Player',
		storeId: 'playerStore',
		proxy: {
			type: 'ajax',
			url: 'players.json',
			reader: {
				type: 'json',
				rootProperty: 'players'
			}
		},
		autoLoad: true,
	}
})
```

```javascript:players.json
{
	players: [
		{
			name: "Wayne Rooney",
			no: 10,
			position: "Forward"
		},
		{
			name: "Daren Fletcher",
			no: 24,
			position: "Midfielder"
		}
	]
}
```

# ajax proxyじゃない時のロード手順
インラインやlocalstorageの（上記のplayers.json形式を返す）ストアの場合は、下記のコントローラーでストアを読んでviewへ値を渡せます。

今回の例ではストアからロードした1番目のnameキーの文字列を返しています。

```AjaxtTest.Controller.Main.js
Ext.define('AjaxTest.controller.Main', {
    extend: 'Ext.app.Controller',
    
    config: {
        refs: {
            mainView: 'main'
        },
        control: {
            'main': {
                activate: 'readJson'
            }
        }
    },

    readJson: function(){
        var store = Ext.getStore('playerStore');
        var view = this.getMainView();
		store.load();
		
		var name = store.getAt(0).get("name");
		view.setData(
			{
				name: name,
			}
	    ) 
    },

    //called when the Application is launched, remove if not needed
    launch: function(app) {
        
    }
});
```


これが、今回上記のストアで定義しているようにajaxプロキシ経由で読み込むと次のエラーをはく。

*Uncaught TypeError: Cannot read property 'get' of undefined*

これはajaxプロキシの場合、ストアのロードを非同期で行っているため実際にストアをロードする前に実行しようとしているのでメソッドが見つからないことが原因

viewにデータを渡すのではなく ```console.log(store.getCount())``` のようにコンソールに値(この場合はストアのサイズ）を表示しようとしてもストアをロードし切る前に実行されてしまうためやっぱりコンソール上には何も表示されない。


これを回避するためにはloadメソッドの中でコールバック関数を実行してコールバックの中で処理を実行させる必要がある。


# ajax proxy経由の正しいロード手順

```javascript:AjaxTest.controller.Main.js
Ext.define('AjaxTest.controller.Main', {
    extend: 'Ext.app.Controller',
    
    config: {
        refs: {
            mainView: 'main'
        },
        control: {
            'main': {
                activate: 'readJson'
            }
        }
    },

    readJson: function(){
        var store = Ext.getStore('playerStore');
        var view = this.getMainView();
        store.load(function(records, operation, success) {
            var name = store.getAt(0).get('name');
            view.setData({name: name});
        })
        // store.load();
        // store.getAt(0).get("name");
        // view.setData(
        //     {
        //         name: name  ,
        //     }
        // )
    },

    //called when the Application is launched, remove if not needed
    launch: function(app) {
        
    }
});
```

コールバック関数を使わない時になぜちゃんと動いてくれないのかはこの説明が一番わかりやすかった。

[Can’t Load Record from a Sencha Touch Store?](http://www.joshmorony.com/cant-load-record-from-a-sencha-touch-store/)