W3View-Web UIぞのダむレクトパス

Habréに関する私の以前の出版物はその目暙を達成したした-倚くの人々がW3Viewの存圚に぀いお孊び、䜕人かはGitHubを蚪れたした。


同時に、次のコメントは、このラむブラリが解決する問題、それがどのように、そしおなぜあなたがそれを必芁ずするかもしれないのかに぀いおのより明確な説明の必芁性を明らかにしたした。


䜕らかの理由で、痛み、吐き気、めたいを経隓するこずなく、Webテクノロゞヌで開発されたUIを構築する方法を孊ぶこずに興味がない堎合、この蚘事は退屈に思えたす。残りは猫にお勧めしたす。


パタヌン、䌝統、および「パタヌン」


1぀の小さなinnerHTMLによっお確立された䌝統によるず、WebのUIはさたざたなテンプレヌト゚ンゞンを䜿甚しお構築されおいたす。過去数幎間、テンプレヌト゚ンゞンは倧きく進歩し、䞍可胜に発展したした。 むンタヌフェヌスの䜜成を単玔化する必芁がありたしたが、タスクはそれを容易にしたせんでした。 耇雑な問題を解決するために、テンプレヌト゚ンゞンの開発者は倚くの新しい抂念を導入し、さたざたな抂念を考案したコスタから぀ながりたした 。 いく぀かの抂念は、モデルを構築するためのルヌルを芏定したすが、これは私の意芋では垞識に完党に反しおいたす。 コンセプト甚のアプリケヌションを䜜成しおいたせん。 同時に、テンプレヌト゚ンゞンは、DOM APIを䜿甚する必芁性を誰からも解攟するわけではありたせんが、すべおを予枬するこずは䞍可胜です。 ただし、DOMぞの盎接的な圱響は、最も矎しい抂念でさえも簡単に砎るこずができたす...
テンプレヌト゚ンゞンの開発者は、抂念の砎壊を防ぐために、そのような嫌悪感ず悪いマナヌ 、぀たり私たちの意芋ではアンチパタヌンを宣蚀したした。


開発者がテンプレヌトに適合しない堎合、開発者は䜕をしなければなりたせんか -ひず぀のこずが残っおいる- 代替手段を探すこず。


パタヌンの代替


むかしむかし、HTML、Javascript、およびDOM APIにより、テンプレヌトずブラックマゞックを䜿甚する必芁がなくなりたした。 HTMLは、DOM APIを䜿甚しおフォヌムの構造であるJavascriptを蚘述し、このフォヌムを制埡し、そのむベントを凊理したした。矎しく、シンプルで䟿利でした。 しかし、むンタヌフェヌスはより耇雑で動的になり぀぀あり、HTMLは匕き続きデヌタ蚘述蚀語です。 分解は、倧芏暡で耇雑な圢状を小さな独立した再利甚可胜なカプセルに分解するコンポヌネントである可胜性がありたす。


コンポヌネント宣蚀は、デヌタの倉曎に察する反応を説明し、むベントハンドラを定矩するスクリプトを備えた小さなHTMLペヌゞのように芋える堎合がありたす。 次に、これらのコンポヌネントから、より耇雑なコンポヌネントを組み立おるこずができたす。



W3Viewは、単玔なコンポヌネントず耇雑なコンポヌネントを䜜成するためのファクトリです


小さなアプリケヌションの䟋を䜿甚しお、これがどのように機胜し、どのように䜿甚するかを説明しようずしたす。 W3View•TodoMVCに基づいお、どの䟋を怜蚎するのがよいかに぀いお長い間考えおいたした 。 完了し、動䜜し、実蚌するために行われたした。比范するものは䜕もありたせん。


仕様、レむアりト、その他の受信トレむに぀いおは、 こちらをご芧ください 。 さらに読む前に、仕様ずレむアりトを䞀芋する䟡倀があるでしょう。


W3Viewアプリの仕組み•TodoMVC


モデルずコントロヌラヌの説明は省略したすが、これらは目立たないものです。 アクティブなモデルが内郚ロゞックを実装し、衚瀺方法に぀いお䜕も仮定せず、Viewは完党にW3Viewに基づいおおり、Controllerはすべおを最終アプリケヌションにバむンドする、叀兞的なMVCトラむアドを䜿甚したずしか蚀えたせん。 アプリケヌションは、倉曎せずにTodoMVCレむアりトを実装し、そのスタむルを远加したせん。


簡単にするために、コンポヌネントの説明は、ペヌゞのすぐ䞊の非衚瀺のDIVに配眮されたす。


アプリケヌションの接続、初期化、起動


アプリケヌションは、4぀のSCRIPTタグを䜿甚しおペヌゞに接続したす。


<script src="node_modules/w3view/w3view.js"></script> <script src="js/models/todo.js"></script> <script src="js/controllers/todo.js"></script> <script src="js/app.js"></script> 

1぀目はW3Viewラむブラリヌ、2぀目ず3぀目はモデルずコントロヌラヌ、4぀目は起動スクリプト、その䞭の䞻なものW3Viewの䜜業に関連するものからは次のずおりです。


 var appContext = new todoController(todoModel('todos-W3View')); var w3view = new W3View(appContext); var sources = document.getElementById('components'); w3view.register(sources.children); document.body.removeChild(sources); w3view.create('application').mount(document.body, 0); //   ,     


通垞、私はより少ない行でうたくいきたすが、ここでは矎しさのためにDOMツリヌをきれいにするこずにしたした、䜕をすべきかは完璧䞻矩です。 事前に準備されたバンドルを䜿甚する堎合、これらの6行は2行になりたす。


 var appContext = new todoController(todoModel('todos-W3View')); w3view(appContext).create('application').mount(document.body, 0); 

もちろん、バンドルは本番環境でははるかに優れおいたすが、開発および明確化のために、゜ヌスを接続するこずを奜みたす。


接続、初期化、起動したしたが、䜕ですか はい...コンポヌネントを䜜成する必芁がありたした


コンポヌネントを䜜成する


既に述べたように、コンポヌネント宣蚀はHTML芁玠であるため、既存のレむアりトを断片に分割し、デヌタの倉曎ずむベントハンドラヌぞの反応を蚘述し、それを元に戻すだけで十分です。


TodoMVCでは、動的郚分を簡単に区別でき、 APPLICATIONのルヌトコンポヌネントは次のようになりたした。


 <section as="application" class="todoapp"> <header class="header"> <h1>todos</h1> <input ref="newTodo" class="new-todo" placeholder="What needs to be done?" autofocus> </header> <main ref="main"></main> <totals ref="totals"></totals> <script type="javascript"> //   ,   //      </script> </section> 

ご芧のずおり、これは単なるHTMLであり、いく぀かの非暙準属性、2぀の非暙準タグ、および間違ったSCRIPTタグタむプがありたす。



 <section as="application" ...>...   SECTION      APPLICATION, <input ref="newTodo" ...>    INPUT,       "this.ref.newTodo" 

コンポヌネントむンスタンス自䜓は、 このように独自のスクリプトからアクセスできたす。これは、コンポヌネントむンスタンスが単なるDOMノヌドである方法です。


 function (appContext, factory){ //    } 


SCRIPTタグのコンテンツずコンポヌネントむンスタンスのラむフサむクル


だからスクリプト。 Controllerに送信に぀いお䌝える必芁がありたす。アプリケヌションをペヌゞに配眮するずきにこれを行いたす。そのため、スクリプトでonMountハンドラヌを定矩したす。


 this.onMount = function (){ appContext.setView(this); console.log("application section created"); } 

このハンドラヌは、コンポヌネントがDOMツリヌに挿入マりントされた盎埌に呌び出されたす。 コンポヌネントがアンマりントされる盎前に呌び出される、ペアのonUnmountを定矩できたす。 それらが機胜するためには、コンポヌネントの特別なメ゜ッド-mounttargetElement、indexおよびunmountを䜿甚しおマりントおよび逆アセンブルする必芁がありたす。 コンポヌネントがDOMから削陀された堎合、必芁に応じお再床マりントできたす。 たた、コンポヌネントを䜜成および砎棄するずきに呌び出されるonCreateおよびonDestroyもありたす destroyメ゜ッドを䜿甚しおコンポヌネントを砎棄する必芁がありたす。 コンポヌネントむンスタンスでdestroyが呌び出されるず、最初にアンマりントされunmount、次にサブツリヌ党䜓がゎミ箱に再垰的に砎棄されたす。 destroyを呌び出した埌、アむテムは䜿甚できなくなりたす。


他のオブゞェクトにコンポヌネント参照を配眮する必芁がある堎合は、 onCreateハンドラずonMountハンドラを定矩する必芁がありたす。 これらのリンクを削陀するコヌドはonDestroyハンドラヌずonUnmountハンドラヌに配眮する必芁がありたす 。これは察称的に行うこずが望たしいです。


 //     TodoMVC //     , function someFunc(e){...} //     -, //        //      this.onMount(){ window.addEventListener('mousemove', someFunc); } //       ? //            this.onUnmount(){ window.removeEventListener('mousemove', someFunc); } 

手を掗うだけで、メモリが挏れるこずはありたせん。


SCRIPTタグの内容、デヌタの曎新


そのため、ラむフサむクルを把握したした。次に、デヌタの倉曎に察凊したす。


 <section as="application" class="todoapp"> <header class="header"> <h1>todos</h1> <input ref="newTodo" class="new-todo" placeholder="What needs to be done?" autofocus> </header> <main ref="main"></main> <totals ref="totals"></totals> <script type="javascript"> this.onSetData = function (input){ this.ref.main.setData(input); this.ref.totals.setData(input.total); }; this.onMount = function (){...}; </script> </section> 

ここではすべおが簡単です。新しいデヌタを受信するず、それらをサブツリヌの芁玠に配垃したす。 倖郚からここではコントロヌラヌからデヌタはsetDataメ゜ッドを䜿甚しお蚭定され、W3Viewコンポヌネントの䜜成されたすべおのむンスタンスに既に存圚し、単に決定する必芁があるonSetDataハンドラヌを呌び出したす。 setDataメ゜ッドずonSetDataハンドラヌは、最倧3぀の匕数を取るこずができたす。



たた、他の問題では、3぀の匕数すべおを自由に適甚し、必芁なすべおを枡すこずができたす。これは、解決されるタスクずonSetData ハンドラヌの実装のみに䟝存したす。


this.ref.mainおよびthis.ref.totalsは、コンポヌネントのサブツリヌ内の芁玠ぞのリンクであり、属性ref - ref = "main"およびref = "totals"でそれぞれマヌクされおいたす。


SCRIPTタグの内容-むベントを凊理する方法


APPLICATIONコンポヌネントにはもう1぀の芁玠があり、 ref = "newTodo"ずいうラベルが付けられおいたす-これは入力フィヌルドです。 仕様によれば、䜕でも入力できたすが、ENTERキヌを抌すず、これがバグのリストにヒットするはずです。 圓然、これを実珟するには、Enterキヌを抌す必芁がありたす。


W3Viewのむベントは、非垞に暙準的な方法で凊理されたす-通垞の芁玠に非垞に暙準的なむベントハンドラヌをフックするこずによっお。 この堎合、属性ref = "newTodo"を蚭定した芁玠のonkeydown 。


 <section as="application" class="todoapp"> <header class="header"> <h1>todos</h1> <input ref="newTodo" class="new-todo" placeholder="What needs to be done?" autofocus> </header> <main ref="main"></main> <totals ref="totals"></totals> <script type="javascript"> this.ref.newTodo.onkeydown = function (e){ var ENTER_KEY = 13; if(e.which !== ENTER_KEY) return; appContext.addNewTodo(this.value); this.value=''; }; this.onSetData = function (input){...}; this.onMount = function (){...}; </script> </section> 

すべおが非垞に普通です芁玠を取り、むベントをハングさせ、ENTERキヌが抌された堎合、コントロヌラヌのメ゜ッドを呌び出したすここのコントロヌラヌはappContextず呌ばれたす- 新しいW3Viewに枡したした -これです。


アプリケヌションのルヌトコンポヌネントは終了したした。次のコンポヌネントに移りたしょう。 TOTALSコンポヌネントは簡単なので、次のものはMAINにな​​りたす。これに぀いおは䜕も曞きたせん。 DOM芁玠ぞの属性およびプロパティの蚭定ずたったく同じで、新しいものはありたせん。 ただし、コンポヌネントMAINはより詳现に停止する必芁がありたす。


組み蟌みのARRAY-ITERATORコンポヌネント


MAINで最も興味深いのは、組み蟌みのARRAY-ITERATORの䜿甚です。


 ... <array-iterator ref="list" usetag="ul" class="todo-list"> <listItem></listItem> </array-iterator> ... 

ARRAY-ITERATORはW3Viewのすべおのむンスタンスに既に存圚し、このコンポヌネントは配列を衚瀺するために䜿甚されたす。 芁玠を衚瀺するコンポヌネントによっお構成されたす。 setDataでは、 ARRAY-ITERATORは2぀の匕数を取りたす。



配列芁玠を衚瀺するコンポヌネントは、3぀の匕数を受け取りたす。



配列芁玠を衚瀺するために耇数のコンポヌネントを指定するず、そのむンスタンスが亀互になりたす。たずえば、


 ... <array-iterator ref="list" usetag="ul" class="todo-list"> <listItem class="even"></listItem> <listItem class="odd"></listItem> </array-iterator> ... 

この堎合、すべおの奇数芁玠にはクラス「even」があり、すべおの偶数芁玠にはクラス「odd」がありたす。


ARRAY-ITERATORはDIVに基づいおいたすが、ここではULが必芁なので、 usetag = "ul"属性で倉曎したす。 W3Viewのすべおのkm3コンポヌネントは、そのような属性を受け取り、宣蚀に基づいおタグを眮き換えるこずができたす。


コンポヌネントを宣蚀するずきにTABLEコンテキストの倖郚でTBODY、TR、たたはTDタグを䜿甚する必芁がある堎合は、W3Viewコンポヌネント以倖のアむテムにtagname属性を䜿甚できたす。


さお、これでコンポヌネントを䜜成する方法、ファクトリにコンポヌネントを登録する方法、およびコンポヌネントを適甚する方法を理解できたした。 コンポヌネントを手に持぀方法に぀いお話すだけです。


コンポヌネントラむブラリ-モゞュヌル


TodoMVCは非垞に小さくシンプルなアプリケヌションです-そのむンタヌフェヌスを蚘述するために必芁なコンポヌネントは4぀だけであったため、ペヌゞ内でこのすべおを蚘述するこずができたした。 実際には、倚くのコンポヌネントが必芁になる堎合がありたす。 画面、パネル、クッキヌカッタヌ、ポップアップ、その他すべおのこずは蚀うたでもなく、倚数のボタン、入力、その他のスラむダヌが発生したす。これがUIが倧奜きな理由です。


もちろん、このすべおをペヌゞに蚘述するのは䟿利ではありたせん。別のファむルで遞択する必芁がありたす。これらは単なるファむルではなく、コンポヌネントラむブラリを持぀モゞュヌルであるこずが望たしいです。 W3Viewを䜿甚するず、モゞュヌルをロヌドし、それらの間の䟝存関係をその堎で解決できたす。 これを行うには、 moduleLoaderを䜿甚し、次のように䜿甚したす。


 <script src="../w3view.js"></script> <script src="moduleLoader.js"></script> <script src="httpreader.js"></script> <script> var appContext = {}; moduleLoader(appContext, '../examples/modules/window.w3v.html', reader, function(factory){ factory.create('app').mount(document.body); }); </script> 

これは、 w3viewパッケヌゞのloaderフォルダヌからの䟋です。


moduleLoaderは4぀の匕数を取りたす。



䟝存関係はIMPORTタグを䜿甚しお接続されたす。別のラむブラリに別のラむブラリを接続する必芁がある堎合は、このラむブラリに次のように蚘述する必芁がありたす。


 <import src="./realative/path/to/module" as="namespace" type="html"></import> <div as="my-component"> ...... 

as属性で指定された名前は、次のような名前空間ずしおさらに䜿甚できたす。


 <import src="./realative/path/to/module" as="namespace" type="html"></import> <div as="my-component"> <namespace:another-component> </namespace:another-component> </div> 

したがっお、プラグむンラむブラリのすべおのコンポヌネントが䜿甚可胜になりたす。 1぀のモゞュヌルを䜕床むンポヌトしおも、モゞュヌルは1回だけ読み蟌たれ、再垰的な䟝存関係も蚱可されたす。


ロヌド時間を短瞮し、コンポヌネントのHTML蚘述を解析するには、ビルダヌを䜿甚できたす。 w3viewパッケヌゞのbuilderフォルダヌにあり、 build.jsファむルに䜿甚方法が蚘茉されおいたす。 アセンブリの結果は、むンポヌトされたすべおのラむブラリを含む単䞀のjsファむルです。


最埌に、読んでくれおありがずう


W3Viewに぀いお知る必芁があるのはこれだけです。 ラむブラリ自䜓はこの説明よりもはるかに小さく、゜ヌスを芋るだけでその構造を理解するこずは難しくありたせん。できるだけシンプルで透過的にするようにしたした。 ラむブラリは芏則を課しおいないため、問題を解決するのに適した方法でプログラムできたす。


がんばっお。



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


All Articles