问题
我正在为 emberjs 制作传单视图,但遇到了一些问题。Leaflet 是一个外部库,与问题有些无关,但只知道它是一个映射库。
考虑一个简单的属性,如缩放级别。传单地图实例具有map.getZoom()
可通过 访问和分配的缩放级别map.setZoom(zoomLevel)
。此外,用户可以与地图交互,并更改其缩放级别。Leaflet 允许我们在缩放更改时注册回调。
我希望我的“Ember-Leaflet”视图具有zoomLevel
ember 属性。通过这种方式,我可以从 ember 对象模型中受益(zoomLevel
例如,绑定到模板或另一个值),并且我们正在“使用 ember 方式”进行操作。
基础溶液
我目前拥有的是 Ember.View 的子类,具有 zoomLevel 属性。在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
事件回调)
请注意,我们这里有一种“循环依赖”,即“更改时做某事(在地图上设置缩放) zoomLevel
”和“当某事发生时(用户更改缩放),更改zoomLevel
”。我想要一个可以避免这种循环观察者依赖的解决方案。Ember 的notifyPropertyChange可能是一个解决方案。
对于Ember 的计算属性来说,这似乎是一项理想的任务,但我不知道在依赖属性字符串中放入什么。zoomLevel
基本上是一个属性,它依赖于不是 ember 属性的东西。
更新
我的第一次尝试是使用观察者来设置传单上的缩放并在传单上绑定一个事件zoomend
来设置zoomLevel
我的视图。
问题:当我在 zoomend 传单事件上设置 zoomLevel 时,我会自动再次触发我的观察者。我说清楚了吗?
所以,这一系列事件发生了:
zoomLevel
在交互式地图上更改- 传单火灾
zoomend
事件 zoomend
事件回调设置 emberzoomLevel
- 观察者跑
- 不必要地调用
setZoom
传单
这效率不高,但我不介意它是否有效。问题在于,当用户非常快速地多次更改缩放(在地图上进行简单的长滚动)时,观察者会被多次调用,从而混淆小册子。