HOME > Learning Place >  Ext JS 5 アップグレードガイド

Ext JS 5 アップグレードガイド

Ext JS 5 では、次のような変更や追加を行いながらもできるだけ後方互換性を高めました。

  • 多くの新機能を追加しました
  • 共通のタスクを簡素化しました
  • フレームワークのよく問題を起こしていた部分を調整しました

Ext JS 5 では MVVM アーキテクチャのサポートを導入し、MVC の (C) も進化しました。 これらの進化を調査しそのアドバンテージを手に入れることを推奨すると共に、 これは重要なことですが、既存の Ext JS 4 の MVC アプリケーションが、変更なしで機能し続けられるように努力しました。 このガイドでは Ext JS 5 へアップグレードする際の注意点について説明します。

互換性レイヤー

既存の Ext JS 4.x アプリケーションを Ext JS 5 に移行するための理想的な出発点は新しい互換性レイヤーを有効にすることです。 これは Ext JS 4 にあったものに似ていますが、ロジックをフレームワークの中に移動しました。 このため、互換性レイヤーの有効/無効の切り替えがいままでよりも簡単になります。 さらに、メンテナンスリリースでフレームワークの最新版とズレを起こさないための手助けとなります。 Sencha Cmd が ext-all.js でビルドするとき、またはアプリケーションをビルドする時にオーバーヘッドがなくなります。 そのため、互換性レイヤーは開発段階の時だけ「活性化」します。

互換性レイヤーの目的は注意すべきメソッドの呼び出しを指摘することです。 これはコンソールメッセージや記述のエラーとして表示されます。 場合によっては、互換性レイヤーが以前の動作を復活させますので、その修正は後回しにして、先に進むことができます。

デフォルトの互換性チェック

開発モードでは、互換レベルを指定しなければ Ext JS 5 で廃止されているメソッドを呼び出すとエラーが発生します。 例えば、 Ext.form.field.Trigger の getTriggerWidth() はそういったメソッドの一つです。呼び出すと、次のエラーが発生します。

Ext.form.field.Trigger#getTriggerWidth has been deprecated.

互換性レイヤーを有効にすると、このエラーがコンソールメッセージで出力され、過去の動作が復活します。 全てのエラーを解決したら、互換性レイヤーを無効にしてもそれ以降エラーは発生しないはずです。

互換性を有効にする

アプリケーションのビルドに Sencha Cmd を使っている場合は、アプリケーションの app.json に次のプロパティをセットすると Ext JS 4.2 との互換性を有効にできます:

    compatibility: {
        ext: '4.2'
    }

アプリケーションのビルドに Sencha Cmd を利用してない場合は、フレームワークをロードする前に manifest オブジェクトを指定することで可能になります。

var Ext = Ext || {};
Ext.manifest = { // "app.json" と同じ内容
    compatibility: {
        ext: '4.2'
    }
}

注意すべき変更点

ブラウザ対応

IE6 と IE7 をサポート対象から除外しました。現在、対応しているブラウザは次のものです。

  • IE8+ (標準モードのみ)
  • Firefox (PC & Mac)
  • Safari 6+
  • Chrome (PC & Mac)
  • Opera (PC & Mac)
Doctype

最初に行うべきの変更は DOCTYPE の追加です。HTML5 doctype を推奨しています。 また、インターネットエクスプローラが互換モードを有効にしないように X-UA-Compatible メタタグを設定する事を推奨します。

    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">

doctype を記述していない状態はサポートしていませんので、レガシーブラウザではアプリケーションが動作しません。

アップグレードのこの部分は分かりやすいと思います。 もしあなたのアプリケーションに IE6/7 向けの CSS がたくさんある場合は、 doctype の変更が少し面倒かもしれません。

ディストリビューション

Ext JS 5 では、フレームワークは “ext” という Sencha Cmd パッケージに含まれています。 このため、次の動作を行う際にフレームワークのダウンロードを自動化できます

  • アプリケーションを生成する。 sencha generate app -ext を実行するだけで、Sencha Cmd が Ext JS の最新版をダウンロードして、それを使ってアプリケーションを生成します。

  • アプリケーションをビルドする。 ソースコントロールにアプリケーションをコミットする時に、”ext” フォルダを無視することができますので、sencha app build が必要なフレームワークのダウンロードと解凍を行います。

  • アプリケーションをアップグレードする。 生成する時と同じく、sencha app upgrade -ext を利用すると、アップグレード処理の際に必要なフレームワークをダウンロードします。

パッケージ化するときは、ビルドの出力は build フォルダに保存されます。 Ext JS 5 を Sencha Cmd と一緒に利用せずに、直接使いたい時は、このフォルダが役に立ちます。

packages と src フォルダは Sencha Cmd がアプリケーションに必要なものだけをビルドするために利用します。

アプリケーションをビルドするために Sencha Cmd を利用している場合は、Sencha Cmd 5アップグレードガイド をご覧下さい。 利用していなければ、次へおすすみ下さい。

ext*-dev.js

Sencha Touch では “-debug” と “-dev” を “-debug” にまとめました。 その二つのファイルの違いは、利点よりも多くの混乱を生み出していました。 そのため、Ext JS 5 でも “-dev” ファイルを削除し、”-debug” ファイルには適切なデバックのためだけのセーフティチェックが含まれています。

{theme}.js / {theme}.css

テーマには、コンポーネントのデフォルトコンフィグをチューニングするための、JavaScript のオーバーライドが記述されることがあります。 これは Ext JS 4.2 の Neptune テーマで導入され、今回のExt JS 5 では、 Neptune にデフォルトステータスを与えるように変更されます。 たいていの場合、テーマの JavaScript の部分を含むためには “ext*.js” の後にスクリプトタグが必要です:

    packages/{theme}/build/{theme}(-debug).js

-debug トークンはオプションで、使用するとテーマオーバーライドの圧縮していない JavaScript ビルドを選択します。

コンパイルされたテーマファイルはディストリビューションのルートから次のディレクトリに保存されます。

    packages/{theme}/build/resources/{theme}-all(-rtl)(-debug).css

“-rtl” と “-debug” トークンはオプションです。 RTL サポートが必要であれば、”-rtl” をつけてください。 圧縮していない CSS が必要であれば、”-debug” をつけてください。 どちらか一方だけでも使えますし、両方使うこともできます。また、オプションは指定していなくても問題ありません。

examples/ux

“User eXtensions” は便利なコンポーネントを作成するための起点として提供されています。 そのままでも役立ちますが、コアフレームワークを超えていくためのサンプルとしても参考になります。 ux フォルダは以前とほとんど同じですが、近々 “ext-ux” パッケージに変換されるでしょう。

コンフィグシステムとコンポーネント

Sencha Touch の開発者は既にクラス定義のコンフィグ記法のことはよくご存知だと思います。 Ext JS 5 は後方互換性を高めるためにコンフィグシステムを拡張し、コンポーネントのコンストラクタから initComponent を呼び出す前に initConfig を呼び出すようになりました。 この変更はおそらく、コンフィグシステムを利用しているカスタムコンポーネントに影響を及ぼします。コンフィグプロパティの初期化のタイミングが異なると思いますので、必ず確認して下さい。

新しいコンフィグプロパティを宣言する方法はいつもと同じですが、派生クラスでは直接クラスボディにセットできます。 このため、ベースクラスが古い形式のプロパティをコンフィグシステムのコンフィグプロパティに変換しても、派生クラスはベースクラスとの互換性を保ちます。

あるクラスに役に立つコンフィグシステムの内部的な変更の一つとしては、カスタムの set メソッドは callParent を使って、生成された set メソッドを呼び出すことができることがあげられます。 ただし、クラスが set メソッドを継承していると、生成された set メソッドは適用されません。

宣言型リスナー

Ext JS の以前のバージョンでは、クラスボディに宣言されたリスナーはサブクラスやインスタンスの configs のリスナー宣言があると上書きされていました。

Ext JS 5 以降は、クラスボディに宣言されたリスナーは上書きされません。その代わりに、サブクラスやインスタンスのコンフィグに定義されたリスナーは基底クラスや mixins から継承された既存のリスナーに追加されます。 このため、リスナーは宣言型の方法で安全に定義することができます。

次の例では、三つのリスナーが全て呼び出されます:

Ext.define('SuperButton', {
    extend: 'Ext.button.Button',
    listeners: {
        click: function() {
            console.log('button clicked (superclass handler)');
        }
    }
});
 
Ext.define('SubButton', {
    extend: 'SuperButton',
    listeners: {
        click: function() {
            console.log('button clicked (subclass handler)');
        }
    }
});
 
Ext.create('SubButton', {
    renderTo: Ext.getBody(),
    text: 'click me',
    listeners: {
        click: function() {
            console.log('button clicked (instance handler)');
        }
    }
});

親クラスのリスナーをオーバーライドする宣言型リスナーを使っていたユーザーは、代わりに handler メソッドをオーバーライドするように、コードを変更する必要があります。

DomQuery

Ext JS 5 がサポートしている全てのブラウザでは querySelector() が使えるので、Ext JS 5 では Ext.dom.Query をデフォルトで削除しました。ですから Ext.dom.Query を利用したければ、手動でイングルードする必要があります。 また Ext.dom.Query は使わず、Ext.Element のメソッド(例えば select(), selectNode(), query()) のみ利用することを推奨します。

Ext.dom.Query を使用している場所は置き換えることを推奨しますが、アプリケーションの開始時に Ext.dom.Query を require するという手もあります。 Ext.dom.Query を使い続ける理由としては次の様なものがあるでしょう。

  • “:contains” のようなカスタム “pseudo” セレクターに依存している
  • Ext.data.reader.Xml の中で使っている

DomHelper

DomHelper がHTML マークアップの生成する時の動作に少々の変更があります。 エレメントの属性の値が undefined であれば属性マークアップは生成されません。 値のない属性が必要な場合には、代わりに空文字列を使います。

el.createChild({
    tag: 'div',
    foo: '',
    bar: undefined
});

この例で生成されるエレメントは次の様になります。 <div foo=""></div>.

Grid

Ext JS 5 では、各行は別々の table エレメントです。 これによりブラウザのパフォーマンスが上がります。

バッファードレンダリング

“bufferedrenderer” グリッドプラグインはデフォルトで有効になりました。 これは、画面上に見える列と、スクロールするための少しの余分な行 (設定可能です) のセットだけが描画されることになります。 グリッドがスクロールすると新しい行が追加されます。 反対側の端の行は余分ゾーンの外側に出ると削除されます。

gridbufferedRendererfalse にすると設定を無効にできます。 例えば。

Ext.create({
    xtype: 'grid',
    bufferedRenderer: false,
    ...
});
更新時の自動レイアウト

グリッド行を更新しても、行の高さを可変にしていない限りレイアウトを発生させません。 つまり、いくつかのセルが、可変サイズのフォントやラップしたテキストやイメージなど、任意の HTML を内包するかもしれません。 これらのどれかが使われているならば、次の様にカラムのコンフィグに設定します。

variableRowHeight: true

表示しているカラムが行の高さの変更を発生させたことがわかったら、そのカラムがレイアウトを起動します。 レイアウトは全ての高さ、スクロールバーの表示、カラム幅を設定する事を要求されます。

宣言的セルレンダラー

カラムのセルの renderer は、メソッドの名前を文字列で指定するようになりました。 スコープはカラムに設定された scope になり、それが指定されない場合は、ViewController または直接の親コンポーネントの defaultListenerScope になります。

セルフォーマッター

セルフォーマッターは、Ext.Template のフォーマットトークンで使われるフォーマット指定を設定します。 例えば、formatter: 'round(2)' は小数以下2桁で丸めますし、 formatter: 'date("Y-m-d")' は日付をフォーマットします。

"this" で始まる値 (例えば "this.foo(2)") の時は、”foo” がカラムの scope コンフィグの中にあるということになります。 scope が指定されていない場合は、ViewController または直接の親コンポーネントの defaultListenerScope どちらかが、メソッドのオブジェクトと見なされます。

効率的なセルの更新

カラムには updater コンフィグを設定できるようになりました。 このメソッドはレコードが更新され既存のグリッド行を更新する必要があるときにだけ呼び出されます。 ここには HTML セルエレメントと新しい値が渡され、DOM構造を好きなように操作することができます。

表示されているカラムが value に加えて追加の引数を宣言しているカスタム renderer を使っている場合には、 これらの引数は、生成した行の HTML に影響を与えるために使われるので、 updater は使われません。 したがって、renderer が使われて、新しく HTML 行全体が描画されます。

更新の抑制

ストアが非常に速く更新される場合、更新をバッチにして設定した間隔でフレッシュするように、ビューへの更新を抑制させたい時があります。 グリッドに throttledUpdate: true を設定するとこれを有効にできます。 デフォルトでは、フラッシュ間の遅延は 200 ミリ秒です。 この値は updateDelay コンフィグを使って設定できます。

ウィジェットカラム

Ext.grid.column.Widget は、xtype を含むコンフィグオブジェクトを設定できるカラムです。 このコンフィグオブジェクトは、コンポーネントやウィジェットをカラムの描画されたセルに生成するために使います。

コンポーネントに defaultBindProperty がある場合には、カラムの dataIndex フィールドがそのプロパティにバインドし、コンポーネントはフィールドが変更されると更新されます。

Coming soon: ウィジェットカラムのウィジェットやコンポーネントは、bind コンフィグを使って現在行をカプセル化するViewModel にバインドできます。

非推奨のコンフィグ
  • verticalScroller は無視されます

Grid Filters

Grid filters は feature から plugin に変更されました。 このため、以前 Grid Filter Feature を使っていたグリッドは grid filter はプラグインになっていることを示すために書き換える必要があります。 また、Grid filter はカラムで定義する必要があります。 もう grid filter のコンストラクタにコンフィグで渡すことはできません。 Grid Filter の実装は次のようになります

{
    text: 'Origin',
    dataIndex: 'origin',
    filter: {
        type: 'string',
        value: 'in'
    }
}, {
    text: 'Age',
    dataIndex: 'age',
    filter: {
        type: 'numeric',
        value: {
            gt: 100
        }
    }
}

filter の type は、 カラムに指定された dataIndex の名前によって定義されたフィールドが存在したら、ストアのモデルから決められます。

チャート

ハイパフォーマンスで、タッチ操作に最適化された新しいチャートパッケージを Sencha Touch 2.1 に導入しました。 そのチャートパッケージが Ext JS 5 と Sencha Touch で動作するようになりました。 これには多くの新機能とタブレットデバイスでの素晴らしいパフォーマンスを提供します。

Ext JS 4 までのチャートは別のパッケージに変換されました。 ですから、Ext JS 5 へのアップグレードの移行の手間を極力減らすために過去のチャートはまだ利用できます。 新しいチャートのパッケージへのアップグレードはただ ext-charts パッケージを新しい sencha-charts パッケージに切り替えるだけです。 多くの API は変更されていません。Ext JS チャートから Sencha Charts へのアップグレードに関して、詳しくは Ext Charts アップグレードガイド をご覧ください。

現在の Ext JS チャートはレガシーサポートのために、少なくとも Ext JS 5.1 まではフレームワークに残されます。 しかし、Sencha Charts から導入される新機能や関数は利用できません。

新しいチャートのパッケージはいままでのチャートと似通った部分がたくさんありますが、いくつかの API の違いもあります。

データ

モデル

Ext.data.Model の内部は大きく最適化され、計算フィールド、よりよいアイデンティティ (“id” プロパティ) の管理、宣言されていないフィールドをサポートします。

最後の項目は解き明かすのに少し手間がかかります。 もしフィールドが下記の項目に当てはまるなら、そのフィールドは基本的に fields 配列にリストする必要はありません。

  • デシリアライズ以外の変換が必要ない (例えば JSON から)
  • デフォルト値がない
  • バリデーションする必要がない (Modelレベルで)
プロパティ / コンフィグ
  • data : 宣言されていないモデルフィールドは、以前 Ext JS 4 では取り除かれていましたが、Ext JS 5 ではそのままの状態を維持します。 このため、Model には何らかの処理が必要なフィールドだけ定義します。

  • raw : data プロパティの変更のため、レコードごとに別の raw データプロパティは追跡されません。 もし既存のアプリケーションが Reader が生成したこのプロパティを扱っている場合は、アップデートする前にデータをコピーするシンプルなオーバーライドによって以前とほぼ同じ動作をさせられます。

    Ext.define('App.overrides.data.Model', {
        override: 'Ext.data.Model',
        constructor: (data) {
            this.raw = Ext.apply({}, data);
            this.callParent(arguments);
        }
    });
  • id / internalId : “id” が指定されずにレコードが生成された場合には、”id” が生成されます。 これは Model の “identifier” コンフィグが取り扱います (Sencha Touch からきたもので Ext JS 4 での “idgen”) 。 レコードには “id” として設定され (“getId” でアクセス) 、”data” オブジェクトには idProperty として設定されます。 Ext JS 4 では、”id” は “internalId” にコピーされていましたが、これは変更されました。 “internalId” は別に生成された値で、全てのレコードに渡ってユニークなので、絶対に変更するべきではありません。 しかし、”id” は変更しても大丈夫です。

  • clientIdProperty は Writer のコンフィグとなり、create 操作のためにサーバーに送信されるときに “id” の名前を変更する目的で利用されます。 もし既に存在していたら、生成された “id” が送信されます。 Ext JS 4 と同じく、必要があればサーバーのレスポンスを利用して、サーバーが生成した “id” を返します。 サーバーに送られた “id” は Model に存在している “clientIdProperty” を利用して読み込まれます。 Session を利用している場合には、同じセッション内に管理されているなら、関連しているレコードの「外部キー」フィールドがアップデートされます。

  • modified : 従来は、レコードが変更されていない場合には、Ext.data.Modelmodified プロパティに空のオブジェクトを返していました。 Ext JS 5 では、Model の modified プロパティにアクセスすると、変更されたレコードが追加されていなければ、undefined が返されます。 この変更によりデータパッケージをできるだけスリムにすることができます。 ユーザーは変更を検出するためには、モデルの “modified” メソッド群を使いましょう。次のものがあります。

    • isModified()
    • getModified()
    • getChanges()
  • belongsTo : フィールドの “reference” コンフィグがあるため非推奨になりました。下記をご覧ください。

  • hasMany : 通常の使用方法はフィールドの “reference” コンフィグがあるため非推奨になりました。下記をご覧ください。 foreign key を含まない子 items を記述するための hasMany はまだサポートされています。

  • associations : このコンフィグは belongsTo と hasMany の別の表現方法なので、上記と同じです。

  • persistenceProperty : このプロパティは廃止されました。

  • validations : サポートされていますが、単一のフィールドに関連する validators を生成することは非推奨です。 そのため、フィールド名がキーになっている validators コンフィグオブジェクトを利用して下さい。

メソッド
  • constructor : レコードの生成は、data オブジェクトを渡すだけです。 二つ目の引数は所有するセッション (下記をご覧ください) です、これはユーザーコードで渡すべきではありません。これは Session で利用します。

  • destroy / erase / drop : “destroy” は「サーバーからレコードを削除する」という意味と、Ext.Base のオブジェクト向けの定義では「オブジェクトが利用しているローカルのリソースを整理する」という異なる意味がありました。 このため、Sencha Touch では Model の “destroy” メソッドを “erase” という名前に変えました。 この新しい名前はマージしたデータパッケージの一部となっています。またレコード削除の印をつける “drop” メソッドも追加されました。こちらはすぐに保存しません。言い換えれば、”erase” は “drop” して、”save” することと同じです。 “destroy” はフレームワークの他の部分と同様に、オブジェクトをクリーンナップする機能に変わりました。

フィールド

フィールドで大きく変更された部分は、それぞれのフィールドタイプは小さなクラス階層 (Ext.data.field.* ) でクラスとして定義されるようになったことです。 エイリアス (例えば、’data.field.foo’) を与えるだけで、カスタムフィールドタイプを作成し、それをModel の フィールドで type コンフィグ (例えば ‘foo’) として利用できます。

  • depends : “convert” 関数が自分の値を計算するために使用するフィールド名を宣言できますので、どのフィールドにセットされても自動的にアップデートされます。

  • calculate : この新しいコンフィグで、レコードのデータオブジェクトからフィールドの値を生成するシンプルな関数を作成できるようになります。 “convert” 関数と “depends” 配列を宣言する代わりに、この関数のテキストはフィールドの依存性を調べるために解析されます。

  • reference : ある Model を他の Model と簡単に関連づけするため、フィールドに他のレコードの id (外部キー) を含む場合には、このコンフィグを追加して、参照されている Model の名前を設定します。 これで この Model と参照された Model の関連データの両方を取り込むことができます。

  • validators : このコンフィグは、カスタムフィールドタイプを派生するときによく利用されますが、有効なフィールド値を記述するルールを簡単に列挙する方法でもあります。

カスタムフィールドタイプを派生する能力は、廃止された Ext.data.Types スタティッククラスの替わりとなっています。

ストア

ストアには、Ext JS 5 でいくつか内部的な変更がありました。 ほとんどは Sencha Touch から受け継いでおり、他は チェインストアをサポートするためのものです。

追加されたもの
  • “beginUpdate” / “endUpdate” : このメソッドはストアに複数の変更を行う前と後に呼び出されます。 これらは内部的なアップデートカウンターを加算/減算して、カウンターが 0 のときに、新しい “beginupdate” や “endupdate” イベントを発火します。 このため、ストアを監視しているビューが、重たい操作の実行を遅らせて endupdate イベントに任せることが可能となります。
変更されたもの
  • “getById” / “getByInternalId” : Ext JS 4 では、getByInternalId だけが マップ検索だったため、internalId は id といつも同じわけではなく、アプリケーションは getById を呼び出す必要がありました。 Ext JS 4 では、リニア検索でしたが、Ext JS 5 では両方がマップ検索で動作しています。

  • “remove” event : Ext JS 4.x では、ストアが各レコードの remove event を発火しました。 しかし、Ext JS 5 では、record の削除 はレコードの配列に対してイベントを一つだけ発火します。

  • “add” event : 従来は add event で送信されたインデックスは、レコードが連続していなくても、最初のレコードだけと一致しました。 現在は add event は連続した範囲で一回送信されます。

  • “datachanged” event : いくつかのケースにおいて、以前の Ext 4 のリリースでは継続的にこのイベントを発火しませんでした。 Ext JS 5 は、”loadData”, “add”, “insert” などの手動一括読み込みメソッド全てにこのイベントが発火されることを確保しました。 注:このイベントはストアがインライン (data:[]) でインスタンス化された時は、最初に発生しません。

  • “destroy” / “destroyStore” : ExtJS 4 では、 “destroy” メソッドはレコードを削除するためにリモートリクエストをサーバに送信していました。 これは、フレームワーク全体での “destroy” の意味 (リソースをクリーンナップするもの) と衝突を起こしています。 これからはインラインでこれが起こると “destroy” メソッドはすぐにストアをクリーンアップします。 サーバーへ削除のリクエストを送信するには (Modelと同じく ) “erase” メソッドを使います。 “destroyStore” は非推奨です。

非推奨・廃止されたもの:
  • “buffered” config: このコンフィグは Ext.create と new 演算子でサポートされていましたが非推奨となりました。 type : "buffered" を使って、バッファードストアを生成するのをおすすめします。 もし Ext.data.Store からストアを派生している場合には、”buffered” コンフィグはサポートされていません。 代わりに、Ext.data.BufferedStore から派生して下さい。 例えば、グリッドストアの設定は次のようになります。
store: {
    type: 'buffered',  //  "buffered: true" に相当します
    ... 
}
  • groupers: 複数のグループレベルのサポートは Ext JS 4 で実現されませんでしたので、groupers はソーターを追加の sorters 以上のものではありませんでした。 これは “grouper” のコンフィグに切り替えられ、以前ストアに設定されていた getGroupString メソッドは grouper で構成されるようになります。 内部構造はネストした grouper をサポートできるようになりつつありますので、その機能が使用可能になったら、このコンフィグは元に戻されると思います。
クラス階層の変更

AbstractStore を利用してカスタムストアクラスを作成している場合や、TreeStore を継承している場合、ストアクラス階層の変更の影響をうけると思います。 関係なければ、この部分は読み飛ばしてかまいません。

この階層の中の新しいクラス (ChainedStore を除き) である ProxyStore と LocalStore はプライベートクラスです。 その二つを直接利用することはプライベートとしてラベルされていますが、それぞれのメソッドとプロパティは、派生クラスからパブリックです。 ProxyStore クラスは、リモートを管理するもので、そのため、このクラスが Ext JS 4 の AbstractStore クラスに最も近いものになります。 LocalStore mixin はレコードのローカルコレクションを管理するメソッドを提供します。

TreeStore

TreeStore の変更は、他に比べて興味深いと思います。 TreeStore はビューの実際のレコードストアになったため、TreeStore のリスナーが動作します。 以前は、ビューに連携されていたのは NodeStore だったため、リスナーは通常 NodeStore に記述する必要がありました。

  • get / setRootNode : まだサポートされてはいますが、get / setRoot があるため、非推奨です。 その理由は、root はコンフィグシステムのコンフィグプロパティになったので、これは標準の get / set メソッドです。

ツリーの違うレベルは違うノードタイプを格納します。

生成するノードのタイプはストアのモデルクラスに定義されます。 TreeModel (TreeStoreで使うモデルのベースクラス) は、子ノードを読み込むときに使うTreeModel クラスの略名である、childType コンフィグがセットされます。

読み込むノードタイプを指定するもう一つの方法は、 ストアの ReadertypeProperty を設定する事です。 これは読み込む TreeModel クラスの略名を提供する、生のレコードデータの中のプロパティ名を指定します。

node イベントは TreeStore を通じて不変で中継されません TreeStore はビューを駆動するストアですので、イベント名 ‘remove’、’insert’、’sort’ などの名前のイベントは標準のストアのイベントですからリッスンするビューにとって大きな意味を持ちます。

node イベントは TreeStore を通して中継される前に、先頭に ‘node’ がつけられます。

Proxy
  • “destroy” / “erase”: モデルやストアと同様、destroy メソッドは、リソースをクリーンナップするものに変わりました。 delete リクエストをサーバーに送るには “erase” メソッドを使います。
Reader
  • root : まだサポートされていますが、非推奨です。 他のプロパティ名コンフィグと統一するために、”rootProperty” に名前が変更されました。
Writer
  • root : まだサポートされていますが、非推奨です。 他のプロパティ名コンフィグと統一するために、”rootProperty” に名前が変更されました。
  • writeAllFields: このコンフィグのデフォルトは true でしたが、データ転送を最適化するために false になりました。 このコンフィグは update 時に Writer がフィールドが変更されいなくても全てのフィールドを送信させるときに使います。
Sessions (NEW)

新しい Session クラスは複数レコードとそのアソシエーションの編集の管理をします。 レコードとストアを手動で保存していて、全ての編集を保存するために正確なシーケンスを計算する必要があるとき、Session クラスはとても役に立ちます。 コーディネートされた Model マネージメントを利用できるか判断するためには Ext.data.session.Session の API ドキュメントをご覧ください。

Schema (NEW)

Schema クラス Ext.data.schema.Schema が Model 定義とその関連付けの収集と管理を扱います。 例えば、Schema は一つのクラスが他と相互にアソシエーションを宣言するとき、それを知っていますので、両方のクラスは、クラスが読み込まれた順番に関係なく、適切なアクセサーメソッドで「装飾」されます。

ModelManager (非推奨)

Ext.data.ModelManager クラスは非推奨です。 この機能は Schema に置き換えられました。

Associations

アソシエーションの宣言の方法はスリム化されました。 古いシンタックスはサポートしていますが、ほとんどの場合には、フィールドの新しい “reference” コンフィグが宣言をさらにシンプルにします。 また Ext JS 5 は、manyToMany コンフィグを利用して、「多対多 」のアソシエーションをサポートします。

Ext.data.association.* (置き換えられました)

この名前空間の内容は Schema で置き換えられました。 アプリケーションでそのクラスの直接な利用は珍しいので、このクラスに対するコンフィグ (“belongsTo” など) はほとんどが非推奨ですがサポートされています。

AbstractElement (廃止)

このクラスは廃止され、Element に合併されました (下記をご覧ください) 。

Element

Ext.dom.Element クラスは Ext JS と Sencha Touch の間で統合されました。 この処理の最中に、いくつかのメソッドに細かい変更がありました。

コンストラクター

Ext JS 4 での Ext.dom.Element のコンストラクターは、 “forceNew” パラメータに “true” が渡さない限り、 エレメントキャッシュに存在していればそこからエレメントを返しました。 Ext JS 5 の場合には、いつも新しい Ext.dom.Element インスタンスを作成するように動作が変更されて、forceNew のパラメータは取り外されました。 普段は Ext.get() から Element のコンストラクターが呼び出されますので、Ext.get() は既に cache 検索を実行をしており、余計な cache の確認を避けることができます。 ユーザーは Ext.dom.Element のコンストラクターを直接呼び出さないことを推奨します。 Element のインスタンスが必要であれば Ext.get() または Ext.fly() の利用を推奨します。

Ext.get()

ドキュメントのフラグメントが渡された場合、Ext JS 4 では Ext.get() は null が返されます。 Ext JS 5 では、ドキュメントフラグメントは Ext.get() を利用して、 Ext.dom.Element のインスタンスにラッピングできるようになっています。そのため、Ext.dom.Element の API を完全に利用できるようになります。

Ext.fly()

Ext.dom.Fly は別のクラスになっており、Ext.dom.Element と同じく、コンストラクタを呼び出してインスタンス化するべきではありません。 Flyweight のエレメントのインスタンスを取得するためには、常に Ext.fly() を利用して下さい。 Ext JS 4 と 5 の間での、Flyweight Element の最も大きな違いは、バージョン 5 ではイベントリスナーを追加することができないことです (addListener と removeListener は開発モードでエラーを発生させます) 。 イベントリスナーを追加する Element インスタンスを取得するには、常に Ext.get() を利用して下さい。 Ext.get() を利用すると、Element を内部のエレメントキャッシュに追加し、廃棄の時点でリスナーも整理されるようになります。 バージョン 4 では Flyweight Element にリスナーを追加するのは推奨されていませんでしたが、これからは禁止されます。

Ext.fly() にもう一つ小さな変更があります。 もうテキストノードをラップすることはできませんので、テキストノードが渡された場合は、null が返されます。 これは Ext.get() の動作と統一するために変更されました。

Element.create()

Ext JS 4 では Ext.dom.Element は、クラスシステムが生成したデフォルトの静的 create() メソッドを継承しました。 その結果、Ext.dom.Element.create() を利用して Element をインスタンス化することが可能でした (推奨はされませんでしたが) 。 Sencha Touch は Ext.dom.Element にコンポーネントのレンダリング処理の一部で利用されているプライベートのオーバーライドされた create() メソッドがあります。これは Sencha Touch 側の手助けで解決されました。 ノードまたは id をラップする Element を取得するには、Ext.get() か Ext.fly() を利用して下さい。

エレメントの選択メソッド (select, query)

4.x では select() と query() メソッドは内部で Ext.dom.Query を利用していました。これは querySelector と querySelectorAll をサポートしていなかった古いブラウザでも動作できるようにするためでしたが、これはネイティブの querySelector と querySelectorAll が対応していない高度な selector を有効にする副作用もありました。

Ext JS 5 がサポートしているブラウザは全て querySelector と querySelectorAll がありますので、エレメントセレクターを処理するために Ext.dom.Query を使う必要はありません。 そのため、select() と query() のメソッドも querySelector または querySelectorAll を利用するように変更して、Ext.dom.Query の必要条件も排除しました。 Ext.dom.Query が対応している高度のセレクターが必要なユーザーは Ext.dom.Query を直接利用できますし、次のようなオーバーライドで Ext.dom.Element の query() と select() メソッドの古い機能を復活させることもできます

    Ext.define('Ext.ElementCompat', {
        override: 'Ext.dom.Element',
        requires: [ 'Ext.dom.Query' ],
        select: function(selector, composite) {
            var elements;
            if (typeof selector == "string") {
                elements = Ext.dom.Query.select(selector, this.dom);
            }
            else if (selector.length !== undefined) {
                elements = selector;
            }
            return composite ? new Ext.CompositeElement(elements)
                      : new Ext.CompositeElementLite(elements);
        }
    }, function(DQ) {
        Ext.query = function(selector, root, type, single) {
            return DQ.select(selector, root, type, single);
        };
    });
メソッドの変更
  • getAttributeNS – 非推奨です。代わりに getAttribute を利用して下さい。
  • isDisplayed – 非推奨です。 代わりに isStyle(‘display’, ‘none’) を利用して下さい。
  • getStyleSize – 非推奨です。フレームワークの内部的な使用のためのものでしたが、フレームワークは使用していません。
  • getComputedWidth – 非推奨です。 代わりに getWidth を利用して下さい。
  • getComputedHeight – 非推奨です。代わりに getHeight を利用して下さい。
  • setLeftTop – 非推奨です。その代わりに setLocalXY 利用して下さい。
  • setBounds – 非推奨です。 その代わりに setBox 利用して下さい。
  • isBorderBox – 非推奨です。IE6/7 はサポートしていないため、全てのブラウザは border-box を使用しています。
  • relayEvent – 廃止されました。Ext.Element は Ext.mixin.Observable を使うようになったので、Observable のプライベートメソッド relayEvent メソッドと衝突したためです。relayEvent の機能が必要であれば、Observable の relayEvents() メソッドを利用して下さい。
  • isTransparent – 非推奨です。
  • getHTML – 非推奨です。代わりに getHtml を利用して下さい。
  • replaceWith – 非推奨です。 代わりに replace() を利用して下さい。

次のプライベート、またはドキュメントされてないメソッドを Ext.dom.Element から廃止しました

インスタンスメソッド: getViewWidth, getViewHeight, getStyles, addToCache, updateCacheEntry, hasMetrics

静的メソッド: addUnits, isAncestor, getX, getY, getXY

EventManager

新しいイベントシステムは Ext.EventManager を使用していませんので、非推奨です。 もし Element にイベントリスナーを追加するためにExt.EventManager を利用している場合は、その替わりに Ext.dom.Element (Observable) API を利用して下さい。 レガシーアプリケーションをアップグレードするために、Ext.EventManager の使用されてないバージョンが提供されていますが、フレームワークの内部で使用されていませんので、明示的に require する必要があります。

AbstractComponent (廃止)

このクラスは廃止されて、Component とマージされました (下記をご覧下さい) 。

Component

Component の最も大きな変更はコンストラクタが initConfig を呼び出すようになったことです。 コンフィグシステムを利用する派生クラスは潜在的な変更の原因となるタイミングを考慮する必要があります。このクラスは自分で initConfig を呼び出すべきではありません。

コンフィグシステムのサポートの一部として、プロパティがコンフィグシステムを利用しているかどうかによって、Component の initConfig は二つの方法でタスクを実行します。この派生コンポーネントをご覧下さい

Ext.define('CustomComponent', {
    extend: 'Ext.Component',
    config: {
        foo: 42
    },
    bar: 'value'
});
var cc = new CustomComponent({
    foo: 427,
    bar: 'other'
});

上記のように、クラスがコンフィグシステムを利用しているコンフィグプロパティと、利用してないコンフィグプロパティを宣言することはあまりありません。 しかし、Ext JS のコンポーネントはこのように混ざっていますので、これがどう処理されるか理解しておくのは重要なことです。

コンストラクタの中で、”foo” への値 427 は生成された setFoo メソッドに渡されます。もしこのクラスが setFoo, applyFoo, updateFoo, を提供しているなら、いつも通りコンフィグシステムがそのメソッドを呼び出します。 しかし、”bar” の “other” という値は、コンフィグシステムプロパティが処理される前にインスタンスにセットされます。

言い換えれば、コンストラクタに渡されるコンフィグオブジェクトは以前のバージョンとほぼ同じように扱えます。 プロパティはインスタンスにコピーされます。唯一の違いは、コンフィグシステムプロパティは適切な setter、applier、updater を通して渡されます。これは全て initConfig が管理しています。

コンポーネントへのもう一つの重要な変更は margins コンフィグの削除です。同様に全てのコンテナーレイアウトの dafaultMargins コンフィグも削除されました。 コンポーネントのマージンを設定するただ一つの方法は、margin コンフィグを使うことです。 margins コンフィグを使っていたアプリケーションは、かわりに margin コンフィグを使う必要があります。 レイアウトの defaultMargins を使っていたアプリケーションでは、コンテナーの defaults ブロックの中で marginを設定します。

メソッドの変更
  • setRegion – 廃止されました。代わりに setBox() を使います。

AbstractContainer

このクラスは廃止され、Container にマージされました。

AbstractPanel

このクラスは廃止され、Panel にマージされました。

Panel

Panel ヘッダー

パネルヘッダータイトルは、Ext.panel.Title のインスタンスになりました。 ヘッダーのタイトルを設定する際に柔軟性が増します。 しかし、header.title は、実際のテキストではなく、Ext.panel.Title のインスタンスを参照します。 最大限の互換性のために、Ext.panel.Paneltitle プロパティは、タイトルのテキストを参照しますが、タイトルテキストにヘッダーインスタンスを使ってアクセスしているアプリケーションでは、header.getTitle().getText() を使う必要があります。

パネルヘッダーアイコンは、ヘッダーの Ext.panel.Title コンポーネントの一部になったため、ヘッダーの item として存在しません。 そのため、バージョン 4 でアイコンがある場合と較べて、 titlePosition の動作は影響しません。 titlePosition を使うアプリケーションで、アイコンと関連したタイトルのポジションをコントロールするには iconAlign を代わりに使います。

メソッドの変更

パネルの内側にボーダーレイアウトを使う時、いくつかの追加のメソッドが使えるようになります。 コンフィグシステムと一緒に使うと、二つのセッターの名前が変わりました。

  • setRegion – region コンフィグを設定します。 setBorderRegion の代わりに使います。
  • setWeight – weight コンフィグを設定します。 setRegionWeight の代わりに使います。

Ext.form.Field

Form フィールドのレイアウトは、IE8+ の CSS 機能を利用できるため、大きく変更されました。 フォームフィールドの内部的なエレメントのレイアウトに 関係していた JavaScript を全て取り外し、Ext JS 4 のフォームフィールドレイアウトに利用されていたテーブルエレメントもなくすことができました。 最終目標はフォームフィールドの機能性が変わらないことでしたが、動作に一つ小さな変更がありました。

バージョン 4 では、フォームフィールドの親エレメントの幅がフィールドのデフォルト幅より小さい場合、フォームフィールドが含まれているエレメントの内側に小さくなってフィットします。 そのため、次のような構成が実行できました

    Ext.create('Ext.panel.Panel', {
        renderTo: document.body,
        title: 'Field Test',
        width: 100,
        bodyPadding: 10,
        items: [{
            xtype: 'textfield',
            margin: 0
        }]
    });

バージョン 5 では、widthを直接フィールドに設定するか、レイアウトの設定に含む以外では、フィールドをデフォルト幅より小さくすることはできません。 このため、上記の結果はコンテナの外にフィールドが溢れます。

これには三つの解決方法があります

  1. width コンフィグを利用してフォームフィールドの幅を直接セットする
  2. フィールドの幅をセットするコンテナレイアウトを利用する (‘anchor’など)
  3. ビューの中でフィールドをスクロールさせたい場合はコンテナで autoScroll: true を利用する。

Ext.form.field.TriggerField

どのテキストフィールドにもトリガーを設定できるようになったので、このクラスは非推奨となりました。 新しいトリガーの宣言と管理は簡単です (例えば、必要な場合には隠すことができます) 。 Ext JS 4 では TriggerField とその派生クラスしかトリガーを持つことができず、しかも融通が聞かなかったことと比べれば大きな改善です。

次のように簡単にカスタムトリガー付きのフィールドを生成できます。

    Ext.create('Ext.form.field.Text', {
        renderTo: Ext.getBody(),
        fieldLabel: 'My Custom Field',
        triggers: {
            foo: {
                cls: 'my-foo-trigger',
                weight: 1, // controls display order
                hideOnReadOnly: false, //always visible
                handler: function() {
                    console.log('foo trigger clicked');
                }
            },
            bar: {
                cls: 'my-bar-trigger',
                hidden: true,
                handler: function() {
                    console.log('bar trigger clicked');
                }
            }
        }
    });

“trigger1Cls” と関連するコンフィグの利用はサポートされていますが、名前つきトリガーとそのコンフィグプロパティがあるため非推奨です。

Ext.ComponentManager

このクラスはアプリケーションが直接に利用することは滅多にありませんが、その内部はスリム化され、コンポーネントの HashMap を提供しません。その代わりに、クラスが提供するメソッドを見て、登録されているコンポーネントにアクセスして下さい。

Ext.util.Bindable

このクラスは Ext.util.StoreHolder に名前が変わりました。 データバインドをサポートする新しい Ext.util.StoreHolder と混乱するからです。 いくつかのコンポーネントから使われている、 store コンフィグのサポート追加する内部的なヘルパークラスです。 一般的に広く使われることを想定していません。

SASS / スタイイングAPIの変更

新しい Ext.tab.Tabrotation コンフィグと、 Ext.tab.PanelExt.tab.BartabRotation コンフィグができたので、 実験的な $tab-left-rotate-direction$tab-right-rotate-direction SASS 変数は削除されました。 新しいコンフィグは、どこにタブバーがドッキングされていても、タブをどの方向にでも回転させられるというより多くの柔軟性を提供します。

タブとボタンのスタイリングは 共通のルールと同様のAPI を使うように一体化されました。 $tab-text-padding SASS 変数とextjs-tab-ui mixin への $ui-text-padding パラメーターはリストではなく数値を受け取るように変わりました。

Ext.menu.MenuExt.toolbar.Toolbar 用の Box レイアウトのオーバーフロー スクローラーのスタイリングは、スクローラーアイコンへの UI を指定したパスネームに変わりました。 これにより、メニューやツールバーのデフォルト UI 用の独自のカスタムスクローラーアイコンを提供するテーマは、それらのイメージを次の様に UI 名を含むように変更しなければなりません。

  • menu/scroll-bottom.png -> menu/default-scroll-bottom.png
  • menu/scroll-top.png -> menu/default-scroll-top.png
  • toolbar/scroll-top.png -> toolbar/default-scroll-top.png
  • toolbar/scroll-right.png -> toolbar/default-scroll-right.png
  • toolbar/scroll-bottom.png -> toolbar/default-scroll-bottom.png
  • toolbar/scroll-left.png -> toolbar/default-scroll-left.png

パネルヘッダーは、iconAlign コンフィグをサポートするようになり、この配置はヘッダーのタイトルと関連しています。 これはアイコンはパネルヘッダーの分離したコンポーネントではなくなり、 Ext.panel.Title コンポーネントの一部になったということです。 その結果、ヘッダーが縦に回転すると、タイトルとアイコンが双方共に (以前はタイトルだけが回転しアイコンは回転しませんでした) 回転します。

パネルヘッダーマークアップを単純化させる一環として、パネルヘッダーの “body” エレメントは削除されました。

一貫性の為に、$tip-header-body-padding SASS 変数は $tip-header-padding にリネームされ、extjs-tip-ui() SASS mixin の $ui-header-body-padding パラメータは $ui-header-padding にリネームされました。

一貫性の為、新しい form-field SASS mixins からは、次の SASS 変数が削除されました。

  • $form-field-font
  • $form-toolbar-field-font

代わりに $form-field-font-size$form-field-font-family などを使ってください。

Classic テーマのオーバーライド

Classic テーマはいくつかのクラスをオーバーライドするようになりました。 ext-theme-classic や ext-theme-gray テーマのユーザーで、アプリのビルドに Sencha Cmd を使わない場合は、これらのテーマをバージョン 4 と同じように動作させるためには、ext-theme-classic.js または ext-theme-gray.js をインクルードする必要があります。 アップグレードのこの部分は、Sencha Cmd でアプリをビルドしているユーザーにとっては、Cmd が自動的にテーマのオーバーライドをインクルードするためシームレスになります。

リキッドレイアウトコンポーネント

Ext JS 5 のフォームフィールドとボタンは CSS の「リキッド」レイアウトを使います。これは、JavaScript が介入する必要なく CSS のみを使ってレイアウトを実現しているということになります。 この「リキッドレイアウト」コンポーネントが “form” や “auto” といった適切なコンテナーレイアウトで使われると、レイアウトエンジンは完全にそれらのレイアウト処理をスキップすることができます。 この新しい動作の副作用として、アプリケーション開発者は、ボタンやフォームフィールドの afterLayoutonBoxReady テンプレートメソッドに頼る必要がなくなります。 代わりに afterRender を使うことを推奨します。

詳しい情報

アップグレードプロセスに関して、より詳しいことは次のガイドを調べてください。

Learning Placeトップに戻る

PAGETOP