2

Knockout Google Maps」をグーグルで検索すると、KO ベースの Google マップの実装がかなり見つかります。私が見つけることができたものはすべて、カスタム バインディング ハンドラーを使用するアプローチを採用していましたが、当初はそれを Knockout コンポーネントとして実装するつもりでした。

例:

ここでKOコンポーネントよりもカスタムバインディングハンドラーを好む理由を誰かが正しい方向に向けることができますか?

私の計画されたユースケースはこれです:

住所検索結果のリストを含むページを実装しています。これまでのリストは KO コンポーネントであり、各リスト エントリは、リスト コンポーネントが foreach バインディングで繰り返し呼び出す別の KO コンポーネントによって生成されます。この検索結果のリストの横に、結果エントリもマップに表示する Google マップが必要です。また、リスト、リスト エントリ、およびマップの間には、非常に多くの相互作用があります。

ここに私がこれまでに持っているものがあります:

var GMap = function () {
    var self = this;

    var initMap = function() {
        var map = new google.maps.Map(document.getElementById('map'), {
            zoom: 13,
            center: {lat: 51.4387974, lng: 6.9922915}
        });
    };
  
    initMap();
};
$(document).ready(function() {
  ko.components.register('gmap', {
    viewModel: GMap,
    template: { element: 'gmap' }
  });
  ko.applyBindings();
});
#map {
  height: 400px;
  width: 600px;
}
<script src="https://maps.googleapis.com/maps/api/js?v=3.22"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<gmap></gmap>
<template id="gmap">
  <div id="map"></div>
</template>

4

2 に答える 2

6

コンポーネントとカスタム ハンドラーはまったく別のものです。

カスタム バインディング

基本的に、カスタム バインディングは以下にアクセスできます。

  • それが使用されている HTML コンポーネント
  • バインドされた値 (バインディングに提供される式)
  • 要素内の他のすべてのバインディング
  • $root$parentなどにアクセスできる要素のバインディング コンテキスト

その定義には、次の 2 つの関数が含まれます。

  • init: ウィジェットの初期化、イベント ハンドラーの設定など、初期設定を行うことができます。
  • update: の後に呼び出されinitます。その時点で、バインディング、すべての要素バインディング、コンテキストなどを介してプロパティ (監視可能なプロパティを含む) にアクセスできます。これにより、アクセスされたオブザーバブルが変更されたときに update を呼び出すサブスクリプションが作成されます。

したがって、カスタム バインディングは、DOM 要素と直接対話する必要がある場合に使用する必要があります。たとえば、プロパティの変更、ウィジェットの初期化、イベントのサブスクライブなどです。

成分

コンポーネントがまったく異なります。コンポーネントを定義するときは、次を定義する必要があります。

  • DOM 要素のセットであるテンプレートで、通常はバインディングを使用します。
  • ビューモデル (通常はコンストラクターまたはファクトリー)

コンポーネントを使用する場合:

  • ビューモデルはインスタンス化されています
  • テンプレートが読み込まれます
  • ビューモデルはテンプレートにバインドされています

したがって、コンポーネントを使用すると、ビューモデルとテンプレートを再利用できます

それで、違いは何ですか?

カスタム バインディングは DOM 要素に直接アクセスできるため、DOM 要素とやり取りしたり、イベントをサブスクライブしたり、プロパティを変更したりできます。

コンポーネントは単なるビューモデルであり、特定のビューモデルへのバインディングを持つ DOM 要素のセットです。

したがって、ウィジェット (マップ) を初期化し、Map イベントと対話し、監視可能なプロパティの変化に応答する必要がある Google マップの場合、コンポーネントを使用することはできません。 DOM 要素。(バインディングを含む一連の HTML 要素と、対応するビュー モデルであることを思い出してください。これらの要素と相互作用するロジックを含めることはできません)。

カスタム バインディングは通常、単一の要素に適用されます (ただし、 のようにその子を処理することはできforeachます)。Google マップの場合、マップを表示する要素だけが必要です。

通常、コンポーネントは多かれ少なかれ複雑な DOM 要素のセットであり、「外部から」アクセスすることはできません。メイン ビューモデルとの唯一の通信は、パラメーターを介して行われます。コンポーネントは DOM 要素と直接対話することはできません。ko バインディングを介して行う必要があります。

したがって、Google マップの場合、カスタム バインドが必要であることは明らかです。

コンポーネントを作成するのは、一連の DOM 要素と関連するビューモデルをモジュール化または再利用したい場合にのみ意味があります。これには、Web サービスへのアクセス (AJAX 経由)、計算の実行 (おそらく計算されたオブザーバブルを使用することによる) などの機能も含まれます。等々。たとえば、次のようなコンポーネントを使用してショッピング カートを実装できます。

  • カート内のアイテムを表示する DOM 要素 (おそらく HTML テーブルといくつかのコントロール)
  • カートの内容を変更するためのコントロール (要素の削除や数量の変更など)
  • 合計、税金などを表示するビューモデル
  • 後でカートを保存する機能、またはカートの代金を支払う機能 (サービスへの ajax 呼び出しである可能性があります)

この場合、カートには、計算されたオブザーバブル (合計と税金を表示するため)、アイテムの削除、数量の変更、保管または支払いなどの機能を含むビューモデルがあります。そして、このビューモデルのバインディングを持つ DOM 要素の具体的なセット、つまり、カートを表示して操作するための HTML です。

Google マップの場合、コンポーネントは、カスタム バインディングの助けがなければ使用できませんでし

地図の横に場所のリストを表示し、そのリストを変更したい場合は、リストと関連機能を備えたビューモデルを含むコンポーネントと、Google マップのカスタム バインディングを含む要素を含むテンプレートを使用できます。それは理にかなっています: ビューモデル + いくつかの要素。

結論

これはすべて、カスタム バインディングは通常、バインドされた DOM 要素との深い対話を行うのに対し、コンポーネントは要素とのより高いレベルの対話を行うことを意味します。これは、バインディングを介して行う必要があります。

したがって、それらは非常に異なるレベルで役割を果たします。それらを比較または交換することはできません。

そうすることを主張する場合、要素を完全に制御し、ビューモデルに完全にアクセスできるため、コンポーネントのように動作するバインディングの獣を作成できますが、それはコンポーネントよりも実装が困難です。そしておそらく、何らかの難解な方法でその逆を行うこともできます.

于 2016-01-07T12:33:37.123 に答える