問題
emberjsのリーフレットビューに取り組んでいますが、いくつか問題があります。リーフレットは外部ライブラリであり、質問とは多少関係がありませんが、マッピングライブラリであることを知っているだけです。
ズームレベルのような単純なプロパティを考えてみましょう。Leafletマップインスタンスには、を介してアクセスmap.getZoom()
および割り当て可能なズームレベルがありますmap.setZoom(zoomLevel)
。また、ユーザーはマップを操作したり、ズームレベルを変更したりできます。リーフレットを使用すると、ズームが変更されたときにコールバックを登録できます。
zoomLevel
「Ember-Leaflet」ビューに残り火プロパティを設定したいと思います。zoomLevel
このようにして、残り火オブジェクトモデル(たとえば、テンプレートや別の値にバインド)の恩恵を受けることができ、「残り火の方法」で実行しています。
基本ソリューション
私が現在持っているのは、zoomLevelプロパティを持つEmber.Viewのサブクラスです。で、リーフレットdidInsertElement
マップインスタンスを作成します。コードはコメント化されており、自明である必要があります。
App.Leaflet = Ember.View.extend({
classNames : ['ember-leaflet'],
//default zoom level
zoomLevel : 13,
didInsertElement : function() {
var self = this;
var zoomLevel = this.get('zoomLevel');
// create map instance
var map = L.map(this.$().get(0)).setView(center, zoomLevel);
// configure map instance...
// Event listeners
map.on('zoomend', function(e) {
self.set('zoomLevel', e.target.getZoom());
});
// save map instance
this.set('map', map);
}
});
チェックリスト
この質問をより「答えやすい」ものにするために、この問題の解決策は次の要件を満たす必要があると思います。
- プロパティ
zoomLevel
が変更されると、マップはそれに応じてズームレベルを変更する必要があります(を使用してmap.setZoom(zoomLevel)
) - ユーザーが地図上のズームをインタラクティブに変更する場合は、
zoomLevel
プロパティを変更する必要があります(おそらくリーフレットマップのzoomend
イベントコールバックを使用して)
ここに一種の「循環依存」があることに注意してください。つまり、「変更時に何かを実行する(マップ上でsetZoom)zoomLevel
」および「何かが発生したときに(ユーザーがズームを変更する)、変更するzoomLevel
」ということです。この循環オブザーバーの依存関係を回避できるソリューションが必要です。EmberのnotifyPropertyChangeが解決策になる可能性があります。
これは、 Emberの計算されたプロパティにとって理想的なタスクのように見えましたが、依存するプロパティの文字列に何を入れるべきかわかりませんでした。zoomLevel
基本的には、残り火のプロパティではないものに依存するプロパティです。
アップデート
私の最初の試みは、オブザーバーを使用してリーフレットのズームを設定し、リーフレットのイベントをバインドしてビューzoomend
を設定することでした。zoomLevel
問題:zoomendリーフレットイベントでzoomLevelを設定すると、オブザーバーが自動的に再度トリガーされます。私は自分自身を明確にしましたか?
したがって、この一連のイベントが発生します。
zoomLevel
インタラクティブマップで変更- リーフレット火災
zoomend
イベント zoomend
イベントコールバックは残り火を設定しますzoomLevel
- オブザーバーが実行します
setZoom
不必要にリーフレットを要求する
これは効率的ではありませんが、うまくいったかどうかは気になりません。問題は、ユーザーがズームを非常にすばやく複数回変更すると(マップ上の単純な長いスクロール)、オブザーバーが複数回呼び出され、リーフレットが混乱することです。