ExtJSのgridでstatefulが効かない


ExtJSのgridでは stateful を true にして stateId を設定するだけで
グリッドのサイズ、カラムの幅や順番・表示/非表示といった状態が
ブラウザに記憶されるようになり、とても便利です。

ところが今回、statefulになるように設定しても
なぜかgridの状態が記憶されない現象にはまってしまいました。

あれこれ悩んでたどり着いた原因は
cookieのサイズオーバー。

  • 100列以上のカラム
  • field名(dataIndex)が日本語

というgridだったのですがstateを表すvalueが7000byte超になっていました。
chromeの場合、1クッキーあたりの最大サイズが4096byteということで
これをオーバーしているため保存できず、stateが記憶されなくなっていたのでした。

errorもwarningも出ず、ステップ実行で追っても
chromeの内部コードに迷い込んで出て来れなくなる
という状態だったので原因になかなかたどり着けませんでした。。

原因が分かったので、対策としては

  • stateのプロバイダーにCookieProviderではなくLocalStorageProviderを使うようにする
  • CookieProviderで保存するcookieのサイズが大きい場合はwarningが出るようにする

を行いました。

cookieのサイズが大きすぎる場合に、warningを出すようにするオーバーライド
Ext.define('MyApp.overrides.state.CookieProvider', {
    override: 'Ext.state.CookieProvider',

    setCookie: function(name, value) {
        var MAX_SIZE = 4096,
            me = this,
            cookie = me.prefix + name + "=" + me.encodeValue(value) + ((me.expires == null) ? "" : ("; expires=" + me.expires.toUTCString())) + ((me.path == null) ? "" : ("; path=" + me.path)) + ((me.domain == null) ? "" : ("; domain=" + me.domain)) + (me.secure ? "; secure" : ""),
            len = cookie.length;

        if (len > MAX_SIZE) {
            Ext.log({level: 'warn'},
                'Too large cookie(' + len + ' byte > ' + MAX_SIZE + ' byte). ' +
                'You might as well use LocalStorageProvider.');
        }

        document.cookie = cookie;
    }
});