LoginSignup
0
0

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-10-04

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

Controller以外の定義

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' }

        ]
    }
});
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>'
        ),
    }
})
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,
    }
})
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経由の正しいロード手順

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?

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0