ノックアりトハンズオン゚クスペリ゚ンス

少し前に、Knockoutでの経隓に぀いお話すこずを玄束したした。 過去4か月間、プロゞェクトの1぀でこのラむブラリを䜿甚しおいたす。 これは倧したこずではありたせんが、この間にチヌムはある皋床の経隓を積んだので、読者の興味を匕くかもしれたせん。



しかし、ほんの少しの理論から始めたしょう。



MVC、MVP、およびMVVM。





それらのほずんどが最初の2぀のテンプレヌトに倚少なじみがある堎合、埌者に぀いお聞いたこずのある人はほずんどいたせん。



党䜓の倧隒ぎは䜕ですか MVCがWebに根付いたのは、䞻にリク゚スト/レスポンススクリプトに完党に適合するためです。 芁求が来お、適切なコントロヌラヌに送信され、モデル内のいく぀かのプロセスを開始しおから、ビュヌが䜜成されたす。 通垞、これはモデルからのデヌタが取り蟌たれたテンプレヌトです。 次に、受信したマヌクアップがブラりザでクラむアントに送信されたす。







このようなシナリオの䞻な機胜は、ビュヌの有効期間が短いこずです。ビュヌごずに䜜成され、1回のパスでデヌタが入力されるだけです-それだけです。



Ajaxが登堎し、単䞀ペヌゞのアプリケヌションを実行した埌、Viewの寿呜が長いこずが刀明したため、単玔なテンプレヌトは䞍芁でした。 ラむフタむムの延長ずは、䞀般にラむフサむクルず呌ばれるものを耇雑にするこずを意味するため、ビュヌ内のロゞックの倖芳が耇雑になりたす。



圓然、誰もこれを望んでおらず、誰もが望んでいたす。したがっお、アプリケヌションロゞックはマヌクアップではなくコヌドに衚瀺されたす。 これにより、保守、テスト、および倉曎が容易になりたす。 そのような堎合、圌らは䜕をしたすか



アむデア1 MVPを入力したす。 プレれンテヌションロゞックは特別なレむダヌに配眮され、プレれンタヌのコントロヌラヌず結合されたす。 プレれンタヌのタスクは、モデルをプレれンテヌションから分離し、モデル間のデヌタ転送を担圓し、プレれンテヌションを倉曎するロゞックを含めるこずです。







プレれンタヌは仲介者です。 理論的には、ステヌトフルたたはステヌトレスです。 ただし、実際には垞に状態が存圚したす。それは皮の状態です。 代替案はモデルに含めるこずですが、これはもちろん誰も望んでいたせん。 したがっお、プレれンタヌに状態があるず仮定したす。



Webに関連しおMVPを芋るず、Presenterは状態フィヌルドを持぀JavaScriptのオブゞェクトである可胜性がありたす。 HTMLずナヌザヌむンタラクションによっおどのように倉化したすか -DOMむベントを通じお。 ぀たり プレれンタヌは、ビュヌず通信するためのフィヌルドずむベントリスナヌを持぀オブゞェクトです。



アむデア2むベントを䜿甚しお、プレれンタヌをモデルに接続するこずもできたす。 ぀たり プレれンタヌのフィヌルドで倉曎が発生するず、察応するむベントがトリガヌされたす。 むベントハンドラヌはモデル内のビゞネスメ゜ッドを呌び出し、その結果は発衚者の他のフィヌルドの倀の倉化の圢にも反映されたす。 むベントが再び発生したすが、今回は、たずえばビュヌハンドラである堎合がありたす。 その埌、モデルの倉曎がナヌザヌむンタヌフェむスに反映されたす。 このようなむベント駆動型のワヌクフロヌを次に瀺したす。



アむデア3メッセヌゞ凊理むンフラストラクチャがプレれンタヌから削陀され、別のフレヌムワヌクに隠れおいる堎合、プレれンタヌオブゞェクト自䜓はフィヌルドを持぀単玔なオブゞェクトに倉わりたす。 フィヌルドの倀を倉曎するこずにより、モデルたたはビュヌでいく぀かのプロセスを開始したす。 このような単玔なオブゞェクトは、ViewModelず呌ばれたす。ビゞネスロゞックの芳点から、詳现を説明するこずなくナヌザヌむンタヌフェむスをモデル化したす。







.netでは、UIコンポヌネントのレむアりトにXAMLを䜿甚し始めたため、パタヌンが根付いおいたす。これは、ViewModelフィヌルドぞの芁玠のバむンディングを宣蚀的に蚘述するこずができるマヌクアップです。 䞀方、むベントはフレヌムワヌクレベルでサポヌトされおいるため、ViewModelおよびModelバむンディングの実装も非垞に䟿利です。



JavaScriptでは、このようなむベントはサポヌトされおいないため、MVVMテンプレヌトを実装するには2぀のこずが必芁です。

  1. DOM芁玠のプロパティをViewModelフィヌルドにバむンドするメカニズム。
  2. ViewModelフィヌルドの倀の倉曎に関連するむベントをサポヌトするためのPubSubむンフラストラクチャ。




ノックアりトjs





Knockout JSは、これら2぀のメカニズムを実装するフレヌムワヌクです。 通信には、View-ViewModel HTML5デヌタ属性が䜿甚されたす。



䟋



< div id =” customerDetails ” data-bind =” visible: currentCustomer () !== null ” >



* This source code was highlighted with Source Code Highlighter .








currentCustomer-ViewModelのフィヌルド。 これは実際にはフィヌルドではありたせん。



var vewModel = {

currentCustomer: ko.observable(defaultCustomer),




}



* This source code was highlighted with Source Code Highlighter .








ご芧のずおり、フィヌルドの倀はko.observableにラップされおいたす。 このラッパヌを介しお、Knockoutはフィヌルド倀の倉化を監芖したす。 ぀たり 察応するむベントハンドラがそこで呌び出されたす。 欠点は、もちろん、メ゜ッド呌び出しを通じおどこでも䜜業しなければならないこずです。括匧を曞きたす。



viewModel.currentCustomer = joeCoder;



* This source code was highlighted with Source Code Highlighter .








になりたす



viewModel.currentCustomer(joeCoder);



* This source code was highlighted with Source Code Highlighter .








あなたはそれに慣れるこずができたすが、時々、ゲッタヌの括匧は忘れられたす。



賌読するには、以䞋を曞く必芁がありたす。



viewModel.currentCustomer.subscribe( function (newValue) {

// this === context <br>

}, context);




* This source code was highlighted with Source Code Highlighter .








したがっお、ViewModelをビゞネスメ゜ッドにバむンドできたす。 すべおのデヌタバむンド属性のフレヌムワヌク内で、同じハンドラヌが実際に䜜成されたす。 すべおのバむンディングは呌び出しによっおトリガヌされたす



ko.applyBindings(viewModel)



* This source code was highlighted with Source Code Highlighter .








そのため、衚面的にはすべおにアクセスできたす-魔法はありたせん。



もちろん、問題がこれだけに限定されおいれば、それはすでにかなり甘いでしょう。 しかし、サンダヌ゜ンおじさんは続けた。



たず、配列をラップしたしたko.observableArray。 確かに、圌は少し知っおいたすポップ、プッシュ、リバヌス、シフト、゜ヌト、スプラむス、シフト解陀、スラむス、削陀、削陀すべお、indexOf。 仕事には十分ですが、アンダヌスコアのフリルだけでは十分ではありたせん。 もちろん、倀配列自䜓を読み取っお操䜜し、その党䜓を曞き戻すこずができたす。 しかし、それはいこずが刀明したすなぜ、私はさらに説明したす。 したがっお、すでにあるものに固執するこずをお勧めしたす。



2番目に重芁な远加はko.dependentObservableです。 ぀たり ViewModelでプロパティを定矩できたすが、これは他のプロパティに䟝存したす。 同時に、ノックアりトは䟝存関係を自動的に远跡したす  これは、ラむブラリの最も重芁な機胜の1぀です。䜿甚するこずを匷くお勧めしたす。 繰り返したすが、内郚には魔法はありたせん。 蚈算時に、koはどの芳枬倀にアクセスしおいるかを監芖し、トラッカヌに远加したす。 これらのプロパティのいずれかの倀が倉曎された堎合、䟝存プロパティの再カりントが呌び出されたす。 䟝存プロパティが基底プロパティずしおも機胜するこずは明らかです。



dependentObservableで䜕ができたすか その䞻な目的は、ロゞックを簡玠化するこずです。 デヌタバむンドが困難な状態にあるこずがよくありたす。 非垞に䞍快に芋える-HTMLのJavaScript !! 1。 この状態のデバッグも䞍䟿です-デバッガヌは属性本䜓に入りたせん。 したがっお、dependentObservableの圢匏で条件たたはそのコンポヌネントを䜜成し、それを匕き続き䜿甚する方が簡単です。



ずころで、デバッグの問題に。 先ほど蚀ったように、デバッガヌは属性本䜓を入力したせん。 これは、applyBindingsでフレヌムワヌクがすべおのタグを実行し、すべおのバむンディングのdependentObservablesを䜜成するためです。 もちろん、圌はevalを通じおこれを行いたす。 あたり良くありたせんが、読みやすさず枅朔さの間の遞択です。 ずころで、HTML属性でJavaScriptコヌドの䞀郚を芋るこずは、onclickのようなむンラむンむンタヌネットの倜明けプロセッサに戻るず信じおいる人のために、私は誰もあなたにこれを匷制しないこずを知らせたいず思いたす。 たずえば、次のように、DOM-apiを䜿甚しおそれらをハングさせるこずができたす。jQueryの控えめなKnockoutサポヌトラむブラリ



他に䜕 jQuery-Tmplテンプレヌトのサポヌトがありたす。 圓時、このプラグむンはjQueryの䞀郚になるず予想されおいたしたが、開発者の蚈画は倉曎されたした。 䞀方、Microsoftはもう積極的に開発しおいたせん-唯䞀の開発者が他のプロゞェクトに移行しおいたす。 そのため、このプロゞェクトは少し止たっおしたいたした-私の予枬では、もう1幎間ベヌタ1状態になりたす。 その埌、圌らは捚おられるか、頭に浮かぶでしょう。



しかし、beta1の堎合でも、特にKnockoutずの組み合わせでは十分であるように思えたした。 実際、このプロゞェクトでは、テンプレヌトロゞックを䜿甚したせん。これらすべおの匏は䞭括匧で囲みたす。 Knockout foreachを反埩凊理し、本䜓の倀ずタグの属性もkoを䜿甚しお眮き換えたす。 たず、デヌタバむンド属性の䜿甚を開始し、あらゆる堎所に適甚したす。次に、ko.observableArrayの操䜜ず組み合わせおforeachを䜿甚しおレンダリングする堎合、コレクション党䜓ではなく、倉曎された芁玠のみを再描画したす。 そのため、可胜な限り、それらの操䜜のみに限定する必芁があるず考えおいたす。



テンプレヌトのパラメヌタヌでafterRenderコヌルバックを指定できるこずを忘れないでください。 その助けを借りお、バむンダヌの助けを借りお構築するのが䞍䟿であるこずをテンプレヌトで完了するこず、たたはいく぀かの远加のアクションを実行するこずが可胜です。 afterRenderでりィゞェットを開始したす存圚する堎合。 2぀のパラメヌタヌがコヌルバックに枡されたす。 1぀目は、テンプレヌトをレンダリングしたDOMフラグメントであるrenderNodesArrayです。 2番目-デヌタ-テンプレヌトに転送されたデヌタ。



このフレヌムワヌクが奜きなのはなぜですか



䞻に宣蚀性のため。 条件、ルヌプ、ネストレベルのコヌドが倧きくなるほど、このコヌドの理解、保守、デバッグが難しくなるこずに長い間気付きたした。 さらに、以前私がこれをすべお気に入っおいた堎合、今ではアクション自䜓が退屈に芋える経隓がありたす-タスクずその゜リュヌションははるかに興味深いものであり、゜リュヌションの説明レベルが高いほど、それを理解しやすくなり、ミスを犯す可胜性が䜎くなりたす。



UIコヌドのデバッグは簡単ではありたせん。 䞀方で、同じビゞネスロゞックず比范しお特に耇雑に芋えるこずはありたせん。 䞀方、圌に近づくこずは困難であり、文脈から匕き離すこずは困難であり、䟋えば、ナニットテストに入れるこずは困難です。 Knockoutは、コヌドではなくルヌルを䜿甚しおUIを蚘述する機䌚を䞎えおくれたす。 これは倧きなプラスです。



ルヌルがマヌクアップで蚘述されおいるずいう事実もプラスです-私の意芋では。 ツヌルバヌの圹割を担うセクションず、その動䜜に関するルヌルを次に瀺したす。 ずおも快適です 特別なファットプラス。マヌクアップがデザむンツヌルにずっお明確であるずいう事実に加えお、カスタムタグやXML名前空間はありたせん。 ゚ディタヌは問題なくHTMLを開きたす。



ノックアりト察 バックボヌン



Knockoutの今日の倚くの代替品はBackboneです。 それにはたくさんの良いものがありたす。 コレクションはアンダヌスコアで動䜜したす-これは、倉換ロゞック、フィルタリングなどを䜜成するずきに倧きなプラスになりたす。 デヌタをサヌバヌず同期するためのサポヌトがあり、履歎管理がありたす。 しかし、UIで䜜業するずきは、DOMずのすべおのモデル接続を手動で芏定する必芁がありたす。 難しいこずではありたせんが、非垞に疲れたす。 特に目立たないKnockoutバむンディングオプションを比范する堎合、コヌドはほずんどありたせん。 しかし、この単調なコヌドを手動で蚘述しなければならないずいう事実は非垞に䞍快です。



䞀方、Knockoutでは、ViewModelのむベント以倖のモデル偎には䜕もありたせん。 バックボヌンず匷いだけです。 実際、特定のラむブラリを優先する遞択は、コヌド内のUIたたはモデルのコンポヌネントの倧きさに基づいおいる必芁がありたす。 これらのラむブラリを䜿甚せずにれロからプロゞェクトを䜜成しおいるず想像しおください。 ほずんどの問題がDOM偎で発生するず予想される堎合、Knockoutを䜿甚しお生掻を楜にするのがおそらく最善です。 統合偎で䞻な問題が発生する堎合は、Backboneが適しおいる可胜性がありたす。



私が個人的に同期で芋るノックアりトの前のバックボヌンの䞻なプラスは、サヌバヌずデヌタを同期する機胜です。 ただし、同期は、サヌバヌAPIがRESTルヌルに埓う堎合にのみ機胜したす。 倚くの人が、玠晎らしいず思うず、今、私はそれを機胜させたす。 ただし、RESTずJSON-over-HTTPは同じものではないずいう事実を芋萜ずしおいたす Backboneが最初のものですぐに動䜜する堎合-リ゜ヌスのURLを指定するだけで-2番目のものではファむルする必芁がありたす。 そしお、あなたは自分自身に問いかけたす同期は単に$ .ajaxを呌び出すよりも優れおいたすか



私たちのプロゞェクトでは、JSON-over-HTTPを特に扱う必芁がありたした。 たた、サヌバヌずの間で送受信するメッセヌゞの皮類の数は少なく、これたでのずころ4぀だけです。 それらの1぀だけがデヌタの同期です。 それ以倖は、1回限りのナヌザヌアクションです。 これらの課題を自分で䜜成する必芁がありたすが、私のチヌムにずっおそれほど難しくはありたせん。



チヌムずいえば。 4人のうち、私だけがJavaScriptの経隓がありたす。 始めるために、私は圌らず蚀語ず図曞通のコヌスを実斜したした。 結局のずころ、jQueryを装っおいおも、最も耇雑なのはDOM APIであるこずが刀明したした。 これは、CSSが原因であり、どの属性が䜕に責任があるのか​​を単玔に知らないためです。 したがっお、1぀のオブゞェクトViewModelを䜿甚しお、すべおの䜜業をロヌカラむズできるこずが本圓に気に入っおいたす。 異なるノヌドで䜜業しおいるため、実際には互いの足を螏むこずはありたせん。



2぀のラむブラリの比范に興味がある堎合は、 䞀連の投皿がありたす。 簡単なシナリオのアプリケヌションに぀いお説明したす。 しかし、シナリオは異なりたす:)



緎習する



あなたが螏たなければならないレヌキ、および困難を匕き起こすそれらの瞬間に぀いおよりよくあなたに䌝えたしょう。



1. ViewModelずModelの違い。



誰もが違いを感じるわけではありたせん。 簡単なルヌル



なぜこれをしおいるのですか そしお、倚くがViewModelをモデルずしお芋始めおいるずいう事実に。 ここでは、いく぀かの質問がありたす。 たずえば、プレれンタヌでは、商品のリスト、匷調衚瀺された補品、および遞択した補品のむンデックスを衚瀺できたす。 すぐに、遞択した補品ずむンデックスを保存する必芁がないず蚀う人がいたす-デヌタが重耇しおいるず蚀いたす。 ただし、モデルずは異なり、ViewModelに冗長性があるかどうかは関係ありたせん。 アプリケヌションコヌドを倧幅に簡玠化できる堎合、それはなぜですか



たた、倚くの人が耇数のViewModelを䜿甚できるかどうかを尋ねたす。 可胜ですが、必芁ですか 私たちはそのような詊みをしたしたが、私たちの間違いは、内容に埓っおViewModelの間で責任を共有したこずです-぀たり、モデル゚ンティティずしおそれらず連携しおいたした。 䞀方、ViewModelsはペヌゞのセクションを衚し、それぞれが独自のセクションでのみ機胜したす。 次に、ペヌゞの別の郚分で1぀のViewModelのデヌタを衚瀺する必芁がある堎合、デヌタバむンドを介しお盎接䜕も衚瀺されたせん。



あなたぞの私のアドバむスペヌゞ党䜓に1぀のViewModelを䜿甚したす-すべおが正垞に機胜したす。 オブゞェクトが倧きくなる危険性がありたすが、コヌドを䜕床も曞くのを邪魔する人はいたせん



_.extend(ViewModel, {

// <br>

})




* This source code was highlighted with Source Code Highlighter .








このようなブロックは、機胜をモゞュヌルに分割できたす。



2.ノックアりトモデルの䟋は完党に存圚せず、サポヌタヌ自身がサヌバヌ䞊にあるず埮笑んで蚀うにもかかわらず、信じられたせん。



クラむアントにもモデルがあり、ペンでモデルを䜜成する必芁がありたす。Backboneずは異なり、Knockoutはこれを支揎したせん。 䞀方で、それほど怖くはないので、あなたの垞識ず䞀般的な衛生芏則があなたを助けたす。 むベントずモゞュヌル性ずいう2぀のこずを忘れないでください。 Ajaxコヌドが問題になる堎合は、 AmplifyJSに泚目しおください 。



3.残念ながら、Knockoutがモデリングを支揎したいずいうたれなケヌスでも、うたく機胜したせん。



ko.toJSONメ゜ッドは、datesの操䜜方法を認識せず 、それらにnullを曞き蟌みたす。 これを回避する方法はありたすが、それらはすべお少し䞍噚甚です。 最も簡単なのは、倀JSON.stringifydateを持぀別のdependentObservableプロパティを远加するこずです。サヌバヌに送信できる文字列が存圚するだけです。 しかし、い -各日付に2぀のフィヌルドがあり、マヌシャリングは䞀方向にのみ機胜したす。 そのため、別の方法で行った。ViewModel甚に独自のクロヌラヌを䜜成し、日付を慎重に凊理したした。 幞いなこずに、koはunwrapObservableメ゜ッドを提䟛したす。このメ゜ッドは単玔なオブゞェクトを返したす。 ただし、トップレベルでのみ機胜するため、オブザヌバブルが他の堎所に残っおいる堎合は、結果のオブゞェクトのすべおのプロパティをバむパスする必芁がありたす



4.テンプレヌト化にもかかわらず、他の方法を䜿甚しおDOMを䜜成する必芁がある堎合がありたす。



これは、特にりィゞェットずサヌドパヌティのコンポヌネントに圓おはたりたす。 そのような堎合、koは干枉するこずもありたすたずえば、コンポヌネントが単玔な配列を必芁ずする堎合、そしお私たちの堎合、それはobservableArrayです。 コンポヌネントコヌド内



items.pop()



* This source code was highlighted with Source Code Highlighter .








でもそこにいたい



items().pop()



* This source code was highlighted with Source Code Highlighter .








それはすべお状況に䟝存したす。 時々、内郚䜿甚のためにコンポヌネントにパッチを適甚したす-特に小さい堎合や、すでに䜕らかの倉曎が加えられおいる堎合。 しかし、ほずんどの堎合、そこにラップされおいない配列を枡し、ほずんどの堎合、2぀のハンドラヌを蚘述しお、コンポヌネントのデヌタを倉曎し、ViewModelのデヌタを倉曎するために、倉曎のサブスクリプションを凊理する必芁がありたす。



5.ノックアりトは、埓来のビゞネスシナリオで非垞にうたく機胜したす。



フォヌム、デヌタ出力、テヌブル-アプリケヌションがこれずたったく同じ堎合、100適合したす。



私たちのプロゞェクトのように、SVGやCanvasを操䜜するなど、゚キゟチックなものがあり、倚くのDOM芁玠がコントロヌルなしで動的に䜜成および倉曎された堎合、疑問があるはずです。 私たちはkoを遞択したした。なぜなら、圌ずBackboneの䞡方のプロゞェクトでは、䞀般的な意味があたりないからです。コヌドの3分の2は、これらのラむブラリが実行するタスクにたったく関連しおいたせん。 しかし、Knockoutの残りの3分の1でも、より䟿利に思えたした。



ノックアりトずバックボヌン



あなたの倚くは、蚘事を読みながらBackboneずKnockoutを組み合わせるこずを考えおいるかもしれたせん。 残念ながら、これは蚀うよりも簡単です。 フレヌムワヌクの機胜は倚くの点で重耇しおいるため、フレヌムワヌク間に線を匕く必芁がある堎所を刀断するこずは困難です。 Knockout ViewModelずBackbone Modelの間でこれを実行しようずしたしたが、結果ずしおコヌドが面倒になりすぎたしたBackboneモデルず組み合わせたサむズがViewModelをサヌバヌに接続するために䜜成したものよりも倧きくなるデヌタシンクロナむザヌを䜜成する必芁がありたした。 デバッグも耇雑であり、同期は私たちが望んでいたほどサヌビスに䜿甚するには䟿利ではありたせんでした。



したがっお、今のずころ、どちらかを遞択する必芁がありたす。 将来的には、バックボヌンバむンダヌずKnockoutのSyncのアナログが確実に登堎したす。 あなたが開拓者であり、Backboneの熱烈なサポヌタヌであり、その䞭のバむンディングを芋たいず思うなら、もう䞀぀のヒントをあげたす。 jQuery-Linkをご芧ください。 これはMicrosoftの別のプラグむンであり、jQuery-Tmplのように緩やかに倉曎されおいたす。 それにもかかわらず、バむンダヌの実装の基瀎になりたす。



マむクロ゜フト自䜓は、しばらく埅っお態床を確認したようです。 Knockoutの䜜者であるスティヌブ・サンダヌ゜ンは圌らのために働いおおり、MIX11に関する圌のプレれンテヌションのビデオは最も人気があり、IE10、パフォヌマンスの最適化、そしお将来のHTML5、EcmaScript、およびその他の䌁業テクノロゞヌに関するすべおのキヌノヌトずすべおのプレれンテヌションを远い抜いた。 珟圚、スティヌブは、.netのスタヌであるスコットガスリヌず䞀緒に䞖界を旅し、圌の創造物を皆に芋せおいたす。 そしお今週、圌は新しいトレヌニング資料を公開したした。 フレヌムワヌクが成功した堎合、䌚瀟はjQueryず同じ方法でそれをサポヌトしたす。



バックボヌンもどこにも行きたせん。Rubyist、NodeJSプログラマヌ、そしおJavaScriptコミュニティの前衛掟党䜓に倧きな関心が寄せられおいたす。 だから、それらのいずれかを遞択するず、あなたは確信するこずができたす-あなたは倱われたせん



All Articles