絶えず変化する要件と厳しい締め切りにより、ExtJS 4を使用してプロトタイプを作成するようになりました。
開発で遭遇したExtJSの問題は、ExtJSの準備で得た経験をほとんど超えませんでした。
インターネットには、ExtJS 4レベルの基本に関する多くの記事があります。 たとえば、この記事は
http://css.dzone.com/articles/how-use-extjs-4-jqueryに非常に満足してい
ます 。 しかし、ExtJSを使用したいくつかの問題の解決(または作成)に関する深刻な「非現金」記事は多くありません。
ExtJSパッチラボのフレームワークの最初の記事をお読みになることをお勧めします。 ネットワーク...かなり。

フィードでは、
Ext.panel.Gridを
Ext.data.Storeとともに使用することが決定され
ました 。 これらは、ExtJSの使用を選択した基本的なものであると言えます。
なぜ
gridであり、
dataViewではないの
か (後でファイナルはビューを優先してグリッドを放棄しなければならなかった) グリッドは、データの並べ替えとフィルタリングのためのビジュアルモードである「エンドレス」スクロールが気に入っていました。 提供された機会の喜びは、単に圧倒的でした。
Ext.data.Store
データはAPI呼び出しを使用してサーバーから
取得され、生の形式で
Storeクラスの
loadDataメソッドに転送されます。
FoursqureのようなAPIのため、ストアに組み込まれたプロキシは使用しません
でした 。
var myStore = Ext.create('Ext.data.Store', { model: 'Post', filterOnLoad: true, idProperty: 'id', filters: new Ext.util.Filter({ filterFn: function (item) { return item.get("status") > 0; } }) }); … API.Events.get().done(function(posts){ myStore.loadData(posts); });
PostモデルはExt.data.Modelクラスの子孫です。
Ext.define('Post', { extend: 'Ext.data.Model', idProperty: 'id', constructor: function (raw) { return this.callParent([this.prepare(raw), raw[this.idProperty]]); }, prepare: function (raw) { … } });
Postモデルでは、生データは
prepareメソッドを介して
準備されます。 親クラスのコンストラクターでは、データは既に処理済みのフォームに含まれています。
prepareメソッドで行われること:
たとえば、投稿日を文字列から
Dateオブジェクトにキャストする
this.data = new Date(this.data);
...通信テーブルのハッシュを介して
typeIdから投稿名の文字列値を取得する
this.typeName = Dict.post.types[this.typeId];
などなど...
Storeはインスタンス化されたモデルの形式で自身の内部にデータを保存します
。loadDataメソッドは、データがまだ生であるかどうかを確認し、モデルコンストラクターに転送して、配列の各要素でデータを書き込みます。
快適なユーティリティ#1
したがって、
loadDataは生オブジェクトの配列と既にインスタンス化されたモデルの両方を受け入れます。
機能#1
単一のオブジェクトを
loadDataに渡すと 、エラーが発生します。メソッドは、1つの要素からであっても配列のみを予期します。
機能#2
javascriptのオブジェクトは参照によって渡されるため、
loadDataに転送される生データはモデルの配列になります。
API.Events.get().done(function(posts){
そのままロードした後に元のデータが必要な場合は、
Ext.Array.clone()メソッドを使用しますが、このメソッドは
jQuery.extendのようなディープクローニングをサポートしていません。
問題#1
loadDataメソッドには、2番目のパラメーター
appendがあります (ストアの既存のレコードにレコードを追加するにはTrueを追加し、古いレコードを最初に削除するにはfalseを追加します) 。 つまり 新しい投稿はサーバーから送信されるため、既存の投稿に追加する必要があります。 これを行うには、2番目のパラメーターをtrueに設定します 。この場合、ストアはロードフィルタリングを使用します(filterOnLoad = true)
フィルタリングの仕組み:
Storeはすべてのレコードを2つのコレクションに格納します。メインのコレクションは
dataで、非表示のコレクションは
snapshotです。
Storeのキー「filterOnLoad:true」は、何らかの方法でデータをロードするときにストアにフィルターを強制的にチェックさせ、内部ストレージでフィルター処理された
スナップショットを破棄します。
Storeでのフィルターの使用とloadDataメソッドには互換性がありません。ext-all-debug.jsファイルからのリスト(
loadRecordsメソッド
はloadDataなどで使用されます)
loadRecords: function(records, options) { … if (!options.addRecords) { delete me.snapshot; me.clearData(); } me.data.addAll(records); … }
ここに問題があります。この場合、
options.addRecordsは
trueです 。
スナップショットは削除されず、データはメインコレクションにのみ含まれます。
API.Posts.get().done(function(posts){ myStore.loadData(posts);
最初のブートでは2つのエントリのみが通過し、それが2番目のブートですべてです。
me.dataには2 + 10のエントリが含まれ、
me.snapshotには8のみが含まれる 2番目の呼び出しからのデータは、隠されたストレージに入れられませんでした。
コレクションを並べ替えるには、古いフィルターをクリアして新しいフィルターを適用する必要があります。フィルターを「再読み込み」することはできません(非常に奇妙です)。
mystore.clearFilter()メソッドは最後の10レコードを削除します;その結果、リポジトリに8レコードがあります。
解決策
loadRecords: function(records, options) { … if (!options.addRecords) { delete me.snapshot; me.clearData(); } me.data.addAll(records);
問題#2
idPropertyキー
は 、本来の目的には使用されません。
idPropertyフィールドは、データベースの主キーに
相当します。 私たちの場合、データには一意のIDキーがあり、これにより、新しい投稿をリポジトリに追加する必要があります。 投稿を変更する場合、たとえばコメントを追加する場合、リポジトリ内のこのエントリを更新する必要があります。 idProperty = "id"キーが設定された
追加モードの
loadDataメソッドは、この問題を解決するはずです。 しかし実際には、このキーはこれには使用されず、データのマージを自動化することはできません。
ソースをざっと調べてみると、そのような機能が存在するが、使用されていないことがわかりました。 me.data.addAll(レコード)メソッドは、配列だけでなく、キー値オブジェクトも受け入れることができます。 この機能を使用するには、同じ
loadRecordsメソッドをわずかに変更するだけです。
解決策
loadRecords: function(records, options) { … if (!options.addRecords) { delete me.snapshot; me.clearData(); } me.data.addAll(records); if (this.idProperty) { var indexRecord = {}; for (i = 0; i < length; i++) { indexRecord[records[i].data[this.idProperty]] = records[i]; } me.data.addAll(indexRecord); if (options.addRecords && me.snapshot) { me.snapshot.addAll(indexRecord); } records = []; for (key in indexRecord) { records.push(indexRecord[key]); } length = records.length; } else { me.data.addAll(records); if (options.addRecords && me.snapshot) { me.snapshot.addAll(records); } } … }
これらの変更後、キーとして
id値があり、新しいデータを追加できます。それらは複製されません...
PSあなたの編集でソースにクロールするのが悪いことを忘れないでください、
Ext.overrideを使用して
ください 。 したがって、フレームワークのバージョンを更新するときに問題を取り除き、パッチファイルを記述するだけで、新しいバージョンで古い問題を修正する場合は、パッチからソリューションを削除します。
将来的には、ストアのプレゼンテーションとの同期の問題を考慮し、複数の表現がある場合はどうなるかを検討します。
アプリケーションは受け入れられますが、さらに興味深い問題とその解決策があるかもしれません。