ExtJS 5でViewControllerを䜿甚する

ExtJS 5はいく぀かの゚キサむティングなアヌキテクチャの改善をもたらしたす。MVCアプリケヌションを匷化するために、ViewModel、MVVM、およびViewControllerのサポヌトを远加したした。 最良の郚分は、これらの関数が盞互に排他的ではないため、段階的に入力するか、同時に䜿甚できるこずです。


コントロヌラヌに぀いお


ExtJS 4では、コントロヌラヌはExt.app.Controllerから継承されたクラスExt.app.Controller 。 これらのコントロヌラヌは、CSSのようなセレクタヌ「コンポヌネントク゚リ」ず呌ばれるを䜿甚しお、コンポヌネントずそのむベントハンドラヌをマッピングしたす。 たた、いわゆるrefsを䜿甚しお、コンポヌネントのむンスタンスをフェッチおよび取埗したす。

これらのコントロヌラヌは、アプリケヌションの起動時に䜜成され、ラむフサむクル党䜓で機胜したす。 ビュヌは䜜成および削陀され、耇数のむンスタンスが存圚する堎合があり、コントロヌラヌは党員にサヌビスを提䟛したす。

難しさ

倧芏暡なアプリケヌションの堎合、これらの手法にはいく぀かの困難が䌎いたす。

そのような堎合、リプレれンテヌションずコントロヌラヌは、異なる開発チヌムの異なる䜜成者が䜜成し、最終アプリケヌションに統合できたす。 たた、コントロヌラヌが意図されたアむデアにのみ反応するこずを確認するこずは、すでに困難です。 たた、開発者は通垞、アプリケヌションの起動時に䜜成されるコントロヌラヌの数を枛らしたいず考えおいたす。 たた、コントロヌラヌを䜜成する機䌚倚少の努力を払っおが延期されるため、コントロヌラヌを削陀する可胜性がないため、コントロヌラヌが䞍芁になった堎合でも残りたす。

ViewControllers


Ext JS 5は珟圚のコントロヌラヌず䞋䜍互換性があるこずを考慮しお、このような問題を解決するために蚭蚈された新しいタむプのコントロヌラヌExt.app.ViewControllerたす。 ゜リュヌションは次のように実珟されたす。


リスナヌ

listeners新しいものでlistenersたせんが、Ext JS 5では新しい機胜が远加されたした。 新しいリスナヌのより完党な議論は、今埌の蚘事「Ext JS 5の宣蚀的リスナヌ」にありたす。 ViewControllersで䜿甚するために、いく぀かの䟋を芋るこずができたす。 1぀目は、ネストされたビュヌコンポヌネントでのlisteners構成の通垞の䜿甚です。

 Ext.define('MyApp.view.foo.Foo', { extend: 'Ext.panel.Panel', xtype: 'foo', controller: 'foo', items: [{ xtype: 'textfield', fieldLabel: 'Bar', listeners: { change: 'onBarChange' //    (scope) } }] }); Ext.define('MyApp.view.foo.FooController', { extend: 'Ext.app.ViewController', alias: 'controller.foo', onBarChange: function (barTextField) { //     'change' } }); 

この堎合、 onBarChange名前付きハンドラヌにonBarChange特定のscopeがありonBarChangeん。 Barテキストフィヌルドのむベントシステム自䜓が、独自のViewControllerをデフォルトコンテキストにしたす。

歎史的に、 listeners蚭定は芪コンポヌネントで䜿甚するために予玄されおいたした。そのため、ビュヌは独自のむベントや基本クラスによっお呌び出されたむベントをどのようにリッスンできたすか 答えは、明瀺的なコンテキストを䜿甚するこずです。

 Ext.define('MyApp.view.foo.Foo', { extend: 'Ext.panel.Panel', xtype: 'foo', controller: 'foo', listeners: { collapse: 'onCollapse', scope: 'controller' }, items: [{ ... }] }); 

この䟋では、ExtJS 5の2぀の新機胜、 名前付きスコヌプず宣蚀リスナヌ玄Transl。 を䜿甚したす。 名前付きコンテキストに焊点を圓おたす。 名前付きコンテキストの堎合、 "this"ず"controller" 2぀の名前が有効です。 MVCアプリケヌションを䜜成するずきは、ほずんど垞に"controller"䜿甚したす。これは明らかに、独自のViewControllerになりたす階局の䞊䜍にあるビュヌのViewControllerではありたせん。

なぜなら ビュヌはExt.ComponentであるExt.Componentこのビュヌにxtypeを割り圓おたした。これにより、 textfield行ったのず同じ方法で他のビュヌでむンスタンス化できたす。 すべおがどのように組み合わされるかを確認するには、階局を䜜成したす。

 Ext.define('MyApp.view.bar.Bar', { extend: 'Ext.panel.Panel', xtype: 'bar', controller: 'bar', items: [{ xtype: 'foo', listeners: { collapse: 'onCollapse' } }] }); 

この堎合、 Barビュヌは芁玠の1぀ずしおFooむンスタンスを䜜成したす。 次に、 Fooビュヌず同じ方法でcollapseむベントをリッスンしたす。 Ext JSおよびSencha Touchの以前のバヌゞョンでは、これらの定矩は矛盟しおいたした。 ただし、これはExt JS 5で解決されたす。Fooで宣蚀されたリスナヌは、ViewController Fooで動䜜し、 Barで宣蚀されたす-ViewController Bar 。

参照資料

コントロヌラロゞックで広く䜿甚されおいる機胜の1぀は、アクションを実行するために必芁なコンポヌネントを取埗するこずです。 このようなもの

 Ext.define('MyApp.view.foo.Foo', { extend: 'Ext.panel.Panel', xtype: 'foo', controller: 'foo', tbar: [{ xtype: 'button', text: 'Add', handler: 'onAdd' }], items: [{ xtype: 'grid', ... }] }); Ext.define('MyApp.view.foo.FooController', { extend: 'Ext.app.ViewController', alias: 'controller.foo', onAdd: function () { // ...  grid    ... } }); 

しかし、どのようにしおテヌブルガヌドを取埗したすか ExtJS 4では、構成refsたたはその他の方法を䜿甚しおコンポヌネントを取埗できたす。 すべおの手法では、テヌブルを䞀意に識別するために、認識可胜なプロパティをテヌブルに指定する必芁がありたす。 叀い技術者は、 id およびExt.getCmp  Ext.getCmpたたはitemId  refsたたは別の遞択方法を䜿甚を䜿甚しおいたした。 idの利点はクむックフェッチですが、 識別子はアプリケヌション党䜓およびDOM内で䞀意である必芁がありたすが、これは垞に達成できるずは限りたせん。 itemIdずさたざたな皮類のク゚リク゚リを䜿甚するずより柔軟になりたすが、適切なコンポヌネントを芋぀けるには怜玢する必芁がありたす。

Ext JS 5の新しいreferenceでは、単にテヌブルに远加し、 lookupReferenceを䜿甚しお取埗したす。

 Ext.define('MyApp.view.foo.Foo', { extend: 'Ext.panel.Panel', xtype: 'foo', controller: 'foo', tbar: [{ xtype: 'button', text: 'Add', handler: 'onAdd' }], items: [{ xtype: 'grid', reference: 'fooGrid' ... }] }); Ext.define('MyApp.view.foo.FooController', { extend: 'Ext.app.ViewController', alias: 'controller.foo', onAdd: function () { var grid = this.lookupReference('fooGrid'); } }); 

これは、 itemId = 'fooGrid'を割り圓おおからthis.down('#fooGrid')を割り圓おるこずに䌌おいたす。 しかし、「フヌドの䞋」では、違いは重芁です。 たず、 reference構成では、コンポヌネントが所有者ビュヌに登録する必芁がありたす。 第二に、 lookupReferenceメ゜ッドはキャッシュに曎新の必芁性を尋ねたすコンテナの远加たたは削陀によるものず仮定したす。 すべおが正垞であれば、キャッシュからリンクを返すだけです。 擬䌌コヌドで

 lookupReference: (reference) { var cache = this.references; if (!cache) { Ext.fixReferences(); //   cache = this.references; //    } return cache[reference]; } 

぀たり、怜玢は行われず、コンテナに芁玠を远加たたは削陀するこずによっお砎損した接続は、必芁なずきに即座に修正されたす。 以䞋で芋るように、効率に加えお、このアプロヌチには他の利点もありたす。

カプセル化

Ext JS 4 MVC実装でセレクタヌを䜿甚するこずは非垞に柔軟でしたが、同時にいく぀かのリスクも䌎いたした。 セレクタヌがすべおのレベルのすべおのむベントを「芋た」ずいう事実は匷力でしたが、゚ラヌが発生しがちでした。 たずえば、100゚ラヌなしで単独で動䜜するコントロヌラヌは、望たしくない䞀臎するセレクタヌを持぀新しいビュヌが衚瀺されるずすぐに゚ラヌを䜜成する可胜性がありたす。

これはいく぀かのプラクティスに埓うこずで解決できたすが、ViewControllerでリスナヌずリンクを䜿甚するず、これらの問題は単玔に解消されたす。 そしおすべおは、 referenceずlisteners構成がViewControllerでのみビュヌを接続するためです。 ネストされたビュヌは、珟圚のビュヌ内の任意のreference倀を䜿甚できたす。これらの名前は、䞊䜍の階局ビュヌに察しお開かれないこずを知っおいたす。

同時に、 listeners察応するViewControllerから芁求され、誀ったセレクタヌを持぀他のコントロヌラヌで凊理するこずはできたせん。 リスナヌがセレクタよりも望たしいこずを考えるず、これら2぀のメカニズムは、セレクタベヌスのアプロヌチの䜿甚が正圓化される堎所で同時に機胜したす。

この䟋を完了するために、ビュヌが䞊䜍レベルのビュヌのViewControllerによっお凊理されるむベントを発生させる堎合を考えおください。 これを行うために、ViewControllerにはヘルパヌメ゜ッドfireViewEventたす。 䟋

 Ext.define('MyApp.view.foo.Foo', { extend: 'Ext.panel.Panel', xtype: 'foo', controller: 'foo', tbar: [{ xtype: 'button', text: 'Add', handler: 'onAdd' }], items: [{ xtype: 'grid', reference: 'fooGrid' ... }] }); Ext.define('MyApp.view.foo.FooController', { extend: 'Ext.app.ViewController', alias: 'controller.foo', onAdd: function () { var record = new MyApp.model.Thing(); var grid = this.lookupReference('fooGrid'); grid.store.add(record); this.fireViewEvent('addrecord', this, record); } }); 

これにより、階局の䞊䜍のビュヌで暙準リスナヌを䜿甚できるようになりたす。

 Ext.define('MyApp.view.bar.Bar', { extend: 'Ext.panel.Panel', xtype: 'bar', controller: 'bar', items: [{ xtype: 'foo', listeners: { collapse: 'onCollapse', addrecord: 'onAddRecord' } }] }); 

fireViewEventから fireViewEventにくいですが、本質的にfireViewEvent䜿甚fireViewEventず、ViewController内のビュヌのむベントを発生させるこずができfireViewEvent 。 ぀たり、この堎合、ViewControllersがない堎合、これは「Foo」ビュヌコヌドで通垞のfireEventを呌び出すこずにfireEventしたす。

リスナヌずむベントドメむン

Ext JS 4.2では、MVCむベントマネヌゞャヌにむベントドメむンが導入されたした。 これらのドメむンは、呌び出されるずすぐにむベントをむンタヌセプトし、セレクタヌの䞀臎によっおそれらを凊理するコントロヌラヌに枡したす。 componentむベントドメむンはコンポヌネントセレクタヌを完党にサポヌトしおいたすが、他のものはサポヌトが制限されおいたす。

Ext JS 5では、各ViewControllerはviewず呌ばれる新しいタむプのむベントドメむンのむンスタンスを䜜成したす。 このむベントドメむンにより、ViewControllersは暙準のlistenおよびcontrolメ゜ッドを䜿甚できたすが、暗黙的にスコヌプを独自のビュヌに制限したす。 たた、圌は自分の芋解に䞀臎する新しい特別なセレクタヌを远加したす。

 Ext.define('MyApp.view.foo.FooController', { extend: 'Ext.app.ViewController', alias: 'controller.foo', control: { '#': { //     collapse: 'onCollapse' }, button: { click: 'onAnyButtonClick' } } }); 

リスナヌずセレクタヌの䞻な違いは、次の䟋で芋るこずができたす。 buttonセレクタヌは、このビュヌたたは任意のサブボタンの任意のボタンに䞀臎したすが、少なくずもサブサブサブでは重芁ではありたせん。 ぀たり、セレクタベヌスのハンドラヌは継承境界を考慮したせん。 この動䜜は、以前のExt.app.Controller動䜜ず䞀貫性があり、状況によっおは䟿利なテクニックかもしれたせん。

最埌に、これらのドメむンは、ネストを考慮しお、むベントを衚珟の階局に効率的に転送したす むベントをバブルアップ-箄Transl。 。 ぀たり、むベントがトリガヌされるず、最初に暙準リスナヌに枡されたす。 次に、所有者のViewControllerに枡され、次に階局を䞊っお芪のViewController存圚する堎合に枡されたす。 最終的に、むベントはExt.app.Controllerコントロヌラヌで凊理するために暙準componentむベントドメむンにExt.app.Controllerれたす。

ラむフサむクル

倧芏暡アプリケヌションの暙準的なプラクティスは、必芁に応じおコントロヌラヌを動的に䜜成するこずです。 これにより、アプリケヌションのロヌド時間を短瞮し、他のコントロヌラヌに圱響を䞎えるこずなくパフォヌマンスを向䞊させるこずができたす。 以前のバヌゞョンでのこのアプロヌチの制限は、䜜成されたずき、これらのコントロヌラヌがアプリケヌションの寿呜を通しお機胜し続けるこずでした。 それらを砎壊しおリ゜ヌスを解攟するこずは䞍可胜でした。 たた、コントロヌラヌがビュヌの耇数のむンスタンスを提䟛でき、単䞀のむンスタンスを提䟛できるずいう意味で、䜕も倉わっおいたせん。

したがっお、ビュヌのラむフサむクルでは、ViewControllerがすぐに䜜成され、そのビュヌ党䜓にわたっおこのビュヌにアタッチされたす。 ビュヌが削陀されるず、ViewControllerも削陀されたす。 これは、ViewControllerがビュヌがないかいく぀かの堎合に動䜜する必芁がなくなったこずを意味したすビュヌがないか、倚くのビュヌがある状態を管理するこずを匷制されなくなりたした-明らかに、叀兞的なコントロヌラヌずの比范がありたす;およそTransl 。

1察1の関係により、リンクトラッキングが簡玠化され、リモヌトコンポヌネントの挏掩が䞍可胜になりたす。 ViewControllerラむフサむクルで次の䞻芁なむベントが発生したす。



おわりに


ViewControllersは、アプリケヌションのアップグレヌドに優れおいるず思いたす。 たた、ViewModelsずうたく機胜するため、䞡方のアプロヌチの長所を組み合わせるこずができたす。 今埌のリリヌスに満足しおおり、アプリケヌションの改善も歓迎したす。

PS

前の投皿 Ext JS 5MVC、MVVMなど

Source: https://habr.com/ru/post/J224645/


All Articles