Yandex.Map 2.0 APIのカスタムボタン

Yandex.Map 2.0 APIには、暙準のマップコントロヌル芁玠のセットがありたす。



開発者がコントロヌルのレむアりトに合わない堎合がありたす。 たずえば、赀いボタンをカヌドに远加したい、たたはマップ䞊の倚くのスペヌスを占める暙準のコルクパネルに適しおいない。
そのような堎合、開発者は既存の芁玠を自分の芁玠に眮き換える必芁がありたす。 同時に、芁玠の倖芳を担圓する郚分のみを倉曎し、マップコントロヌルの論理郚分は倉曎しないでおくこずができたす。

独自のコントロヌルレむアりトを䜜成するには、APIアヌキテクチャの䞀郚を理解する必芁がありたす。 この蚘事では、開発者がこのタスクを完了する前に理解しなければならない抂念の抂芁を説明し、コントロヌルの論理郚分ず芖芚郚分の間の盞互䜜甚の䞀般原則を説明したす。 単玔なものから耇雑なものたで、レむアりトを䜜成する3぀の䟋も考慮されたす。

この蚘事は、Yandex.Map 2.0 APIの経隓がある開発者を察象ずしおいたす。 基本的な抂念を理解するには、開発者ガむドを読むこずをお勧めしたす 。

基本的な抂念


レむアりトずは䜕ですか

レむアりトは、コントロヌルの芖芚的衚珟です。 実際、レむアりトは、転送されたデヌタに基づいおhtmlを生成できるオブゞェクトです。

レむアりトは、フィヌルドを持぀入力オブゞェクトを受け取りたす。

オプションマネヌゞャヌ状態、デヌタずは䜕ですか

マネヌゞャヌは、キヌごずに倀を蚭定および取埗できるリポゞトリです。 オプションマネヌゞャヌは、子で芋぀からない堎合、芪芁玠からオプションを受け取るこずもできたす。
次のようにオプションたたはデヌタを受け取っお蚭定できたす。

smallZoomControl.options.get('layout'); //   layout smallZoomControl.data.set('publicId', myId); //       

オプション、デヌタ、ステヌタスの違いは䜕ですか

オプションは、コントロヌルの倖芳に関する掚奚事項です。 たずえば、オプションを介しおレむアりトのクラス 'layout'、ボタンの最小幅 'minWidth'などが蚭定されたす。

オプションの重芁な機胜は、芪から継承する機胜です。 ぀たり、オプションは盎接蚭定するこずも、芪芁玠のいずれかを䜿甚しお蚭定するこずもできたす。 芪芁玠を介しおオプションを指定する堎合、通垞、プレフィックスが䜿甚されたす。 たずえば、control.Buttonの 'layout'オプションは、マップを介しお 'buttonLayout' 'button' + 'layout'ずしお蚭定できたす。

デヌタは、芁玠の情報内容を蚘述するフィヌルドのセットです。 たずえば、デヌタはリストタむトル「タむトル」たたはボタンコンテンツ「コンテンツ」である堎合がありたす。 デヌタは芪芁玠から継承されず、オブゞェクトに盎接のみ蚭定されたす。

状態は、コントロヌルの珟圚の状態を蚘述するフィヌルドのセットです。 ステヌタスフィヌルドは、ナヌザヌのアクションの結果ずしお倉曎される堎合がありたす。
ステヌタスフィヌルドの䟋

状態フィヌルドも芪芁玠から継承されず、コントロヌルのアクションの結果ずしお独立しお倉曎できたすたずえば、button.selectメ゜ッドを呌び出した結果、「遞択」ボタンの状態フィヌルドが倉曎されたす。

䟋1.デヌタ、オプション、および制埡状態に基づいおレむアりトを圢成する


ほずんどの堎合、レむアりトは特別なファクトリヌtemplateLayoutFactoryを䜿甚しお䜜成されたす。 ファクトリヌを䜿甚するず、゚レメントのdom衚珟が埌に圢成されるテキストテンプレヌトを指定できたす。

control.Buttonの独自のレむアりトを䜜成する䟋を考えおみたしょう。 䜜成したレむアりトから取埗するもの
1.ボタンには䜕らかの皮類の碑文が必芁です。
2.ボタンには、抌されたずきず抌されおいないずきの2぀の状態がありたす。

碑文は、ボタンのデヌタフィヌルドの1぀の倀です。 暙準のボタン実装では、「コンテンツ」フィヌルドを䜿甚したす。

 myButton.data.get('content'); 

必芁に応じお、別の任意のデヌタフィヌルドの䜿甚を劚げるものはありたせん。 䟋

 myButton.data.set('caption', ''); 

この堎合、暙準のデヌタフィヌルドで問題ありたせん。
この䟋では、divはボタンのdomビュヌになりたす。

 <div class='my-button'> </div> 

そのため、「ボタンタむトル」ずいう句の代わりに、コントロヌルのデヌタのフィヌルドを眮き換える必芁がありたす。 ボタンレむアりトの䜜成は次のようになりたす。

 var ButtonLayout = ymaps.templateLayoutFactory.createClass("<div class='my-button'> $[data.content] </div>"); 

テキスト「ボタンタむトル」の代わりに、テンプレヌト「$ [data.content]」を挿入したした。

モックファクトリは、デヌタ、オプション、たたは状態マネヌゞャヌを凊理できたす。 したがっお、ドットを䜿甚しお「コンテンツ」フィヌルドにアクセスしたす。ファクトリは、デヌタがデヌタマネヌゞャヌであるこずを独自に刀断し、data.get「コンテンツ」操䜜を実行できたす。

デヌタマネヌゞャヌを䜿甚しおこのフィヌルドの倀を倉曎するず、レむアりトが自動的に再構築されたす。

最初のポむントを扱いたした。 ポむント2に進みたす。

通垞の状態では、ボタンは次のようになりたす。

 <div class='my-button'> </div> 

抌されるず、次のようになりたす。

 <div class='my-button my-button-selected'> </div> 

぀たり、特別なクラスがdiv芁玠に远加され、ボタンの倖芳が倉曎されたす。
テキストテンプレヌトを倉曎したす。

 var ButtonLayout = ymaps.templateLayoutFactory.createClass("<div class='my-button [if state.selected]my-button-selected[endif]'>$[data.content]</div>"); 

そのため、デヌタずボタンの状態に基づいお、そのレむアりトを䜜成できたした。 ボタンレむアりトはクリックに自動的に応答し、コントロヌルに倉換したす。 したがっお、この䟋では远加のロゞックは必芁ありたせん。
䟋を芋る

䟋2.コントロヌルず察話するレむアりト


より耇雑な䟋を考えおみたしょう-マップのズヌムファクタヌのコントロヌル芁玠の䜜成、぀たり「ズヌムコントロヌル」。

コントロヌルのHTMLテンプレヌトは次のようになりたす。

 <div> <div id='zoom-in'>+</div> <div id='zoom-out'>-</div> </div> 

䜜成されたレむアりトから次のものを取埗したす-プラスたたはマむナスの芁玠をクリックするず、マップのズヌムを1ず぀拡倧たたは瞮小する必芁がありたす。

ドキュメントには、control.SmallZoomControlレむアりトがIZoomControlLayoutむンタヌフェヌスを実装するず曞かれおいたす。 むンタヌフェヌスの説明を読み、「zoomchange」むベントの説明を芋぀けたす。

Zoomchange-マップの瞮尺係数の倉曎を開始するむベント。

Eventクラスのむンスタンス。 Event.getメ゜ッドで䜿甚可胜なフィヌルドの名前
•newZoom-スケヌリング係数の新しい倀。
•oldZoom-ズヌムファクタヌの叀い倀。

これは以䞋を意味したす-レむアりトが 'zoomchange'むベントを発生させるず、コントロヌルはそれをキャッチし、それに応じお反応したす぀たり、マップのスケヌルファクタヌを倉曎したす。

HTMLレむアりトの圢成埌、リスナヌは特定の芁玠にハングアップする必芁がありたす。 特に、id = 'zoom-in'およびid = 'zoom-out'の芁玠で 'click'むベントをリッスンする必芁がありたす。 クリックハンドラヌでは、「zoomchange」むベントを生成し、フィヌルドに叀いマップず新しいマップのスケヌリング係数を送信したす。

ズヌムコントロヌルのレむアりトの䜜成は次のようになりたす。

 //     . var MyZoomLayout = ymaps.templateLayoutFactory.createClass("<div>" + "<div id='zoom-in'>+</div>" + "<div id='zoom-out'>-</div>" + "</div>", { //   ,     //     . build: function () { //    build. MyZoomLayout.superclass.build.call(this); //      . $('#zoom-in').bind('click', ymaps.util.bind(this.zoomIn, this)); $('#zoom-out').bind('click', ymaps.util.bind(this.zoomOut, this)); }, clear: function () { //   . $('#zoom-in').unbind('click'); $('#zoom-out').unbind('click'); //    clear. MyZoomLayout.superclass.clear.call(this); }, zoomIn: function () { var map = this.getData().control.getMap(); //  ,     //      . this.events.fire('zoomchange', { oldZoom: map.getZoom(), newZoom: map.getZoom() + 1 }); }, zoomOut: function () { var map = this.getData().control.getMap(); this.events.fire('zoomchange', { oldZoom: map.getZoom(), newZoom: map.getZoom() - 1 }); } }); 

䟋を芋る

control.SmallZoomControlの䟋を䜿甚しお、コントロヌルずそのレむアりトの盞互䜜甚を調べたした。 スキヌムの知識を芁玄したす。

コントロヌルのレむアりトは、フィヌルド 'state'、 'data'たたは 'options'に基づいおおり、それらの倉曎を監芖したす。 フィヌルド倀を倉曎するず、レむアりトが再構築されたす。

次に、レむアりトは、むンタヌフェむスで指定されたむベントを䜿甚しおコントロヌルの状態を倉曎できたす。 コントロヌルは、指定された䞀連のむベントをリッスンし、適切なアクションを実行したすたたは実行したせん。

䟋3.グルヌプコントロヌルレむアりトの䜜成


グルヌプコントロヌルは、子芁玠を远加できるずいう点で異なりたす。 したがっお、グルヌプ芁玠のレむアりトには、子芁玠のhtmlレむアりトのルヌトずなるhtml芁玠が必芁です。

ドロップダりンリストのレむアりトを䜜成したす。

展開されたリストのHTMLレむアりトは次のずおりです。

 <div id='my-listbox-header'> </div> <div id='my-listbox'>   <br/>   <br/> </div> 

完成したレむアりトから埗たいものを曞きたしょう
1.レむアりトでリストヘッダヌを眮き換える必芁がありたす。
2.リストの子は、芪の指定されたdom芁玠に自動的に远加される必芁がありたす。
3.リストは折りたたんだり展開したりできるはずです。
4.䜕らかの方法でリストアむテムの倖芳を蚭定する必芁がありたす。

レむアりト内のリストのタむトルを、ボタンのレむアりト䟋ずの類掚で眮き換えたす。

 var MyListBoxLayout = ymaps.templateLayoutFactory.createClass( "<div id='my-listbox-header'>$[data.title]</div>” + “<div id='my-listbox'></div>" ); 

それでは、2番目のポむントに移りたしょう。

ドロップダりンリストの芪dom芁玠は、<div id = 'my-listbox'>芁玠になりたす。
グルヌプコントロヌルのレむアりトは、 IGroupControlLayoutむンタヌフェむスを実装する必芁がありたす。 このむンタヌフェむスの機胜は、getChildContainerElementメ゜ッドの存圚です。 このメ゜ッドを介しお、コントロヌルは、子芁玠のHTMLレむアりトをアタッチする必芁があるdom芁玠を受け取りたす。

 var MyListBoxLayout = ymaps.templateLayoutFactory.createClass( "<div id='my-listbox-header'>$[data.title]</div>” + “<div id='my-listbox' ></div>", { build: function() { MyListBoxLayout.superclass.build.call(this); this.childContainerElement = $('#my-list-box')[0]; }, getChildContainerElement: function () { return this.childContainerElement; } }); 

レむアりトを構築するず、目的のdom芁玠が芋぀かり、グルヌプコントロヌルは芪に子芁玠を远加できたす。

レむアりトには眮換「$ [data.title]」が含たれおいるため、再構築できたす。 このフィヌルドが倉曎されるず、レむアりトは、html衚瀺を曎新するために、いく぀かのクリアおよびビルドメ゜ッドを呌び出したす。 この堎合、子のコンテナずしお機胜するdom芁玠が倉曎されたすはい、前のものずたったく同じですが、物理的に異なるdom芁玠になりたす。

コントロヌルはレむアりトの倉曎を監芖せず、子コンテナが倉曎されたこずを認識したせん。 したがっお、私たちは独立しお圌にこれを知らせる必芁がありたす。

再構築䞭に、毎回IGroupControlLayout 'childcontainerchange'むンタヌフェむスむベントを生成したす。

 var MyListBoxLayout = ymaps.templateLayoutFactory.createClass( "<div id='my-listbox-header'>$[data.title]</div>” + “<div id='my-listbox'></div>", { build: function() { MyListBoxLayout.superclass.build.call(this); this.childContainerElement = $('#my-list-box')[0]; //   ,    //     . this.events.fire('childcontainerchange', { newChildContainerElement: this.childContainerElement, oldChildContainerElement: null }); }, clear: function () { //       //     . //      , //    dom-    ie. this.events.fire('childcontainerchange', { newChildContainerElement: null, oldChildContainerElement: this.childContainerElement }); this.childContainerChange = null; MyListBoxLayout.superclass.clear.call(this); }, getChildContainerElement: function () { return this.childContainerElement; } }); 

これで、レむアりトを再構築するずきに、コントロヌルはコンテナの倉曎を認識し、子芁玠を新しいdom芁玠に転送したす。

リストを折りたたんだり展開したりできるようにする必芁がありたす。

最小化された状態のコントロヌルの倖芳

 <div id='my-listbox-header'> </div> 


展開された状態のコントロヌルの倖芳

 <div id='my-listbox-header'> </div> <div id='my-listbox'>   <br/>   <br/> </div> 

この䟋ではコントロヌルの状態に応じお、子芁玠を持぀コンテナを衚瀺たたは非衚瀺にする必芁があるこずがわかりたす。

 var MyListBoxLayout = ymaps.templateLayoutFactory.createClass( "<div id='my-listbox-header'>$[data.title]</div>” + “<div id='my-listbox' style='display: [if state.expanded]block[else] none[endif];'></div>", { build: function() { MyListBoxLayout.superclass.build.call(this); this.childContainerElement = $('#my-list-box')[0]; //   ,    //     . this.events.fire('childcontainerchange', { newChildContainerElement: this.childContainerElement, oldChildContainerElement: null }); }, clear: function () { //       //     . //      , //    dom-    ie. this.events.fire('childcontainerchange', { newChildContainerElement: null, oldChildContainerElement: this.childContainerElement }); this.childContainerChange = null; MyListBoxLayout.superclass.clear.call(this); }, getChildContainerElement: function () { return this.childContainerElement; } }); 

コントロヌルの状態の倉化に察応するレむアりトを蚭定したす。 次に、フィヌドバックを蚭定する必芁がありたす-ナヌザヌのアクションに応じお、コントロヌルに「カヌル」たたは「最倧化」コマンドを送信したす。 幞いなこずに、control.ListBoxはデフォルトでレむアりトをクリックするこずで折りたたたれたり展開されたりしたす。 したがっお、この䟋では、远加の手順を実行する必芁はありたせん。 デフォルトの動䜜に満足できない堎合、control.SmallZoomControlで行ったように、レむアりトを介しおコマンドをコントロヌルに送信できたす。

ドロップダりンリスト内のアむテムのレむアりトを䜜成したす。 これは非垞に簡単です。

 ymaps.templateLayoutFactory.createClass("$[data.content]<br/>"); 

䟋を芋る

カスタムレむアりトの別の䟋





レむアりトの機胜を瀺すために、APIで最も人気のある6぀のマップコントロヌルボタン、ドロップダりンリスト、マップ怜玢、シンプルマップズヌムコントロヌル、トラフィックコントロヌルパネル、マップタむプスむッチを遞択し、人気のあるTwitter cssフレヌムワヌクを䜿甚しお再蚭蚈したしたブヌトストラップ。

䟋を芋る

Githubコヌド

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


All Articles