问题
我正在为emberjs制作传单 View ,但遇到了一些问题。 Leaflet是一个外部库,与问题无关,但只知道它是一个映射库。
考虑一个简单的属性,例如缩放级别。传单 map 实例的缩放级别可以通过map.getZoom()
进行访问,并可以通过map.setZoom(zoomLevel)
进行分配。此外,用户可以与 map 互动,并更改其缩放级别。传单允许我们在缩放更改时添加register a callback。
我希望我的“Ember-Leaflet” View 具有zoomLevel
ember属性。这样,我就可以从ember对象模型中受益(例如,将zoomLevel
绑定(bind)到模板或另一个值),而我们正在以“ember方法”进行操作。
基本解决方案
我目前拥有的是Ember.View的子类,具有zoomLevel属性。在didInsertElement
上,我创建Leaflet映射实例。该代码已注释,应不言自明。
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);
}
});
检查 list
为了使这个问题更“可回答”,我认为该问题的解决方案应满足以下要求:
zoomLevel
时, map 应相应地更改其缩放级别(使用map.setZoom(zoomLevel)
)zoomLevel
属性(可能使用传单 map 的zoomend
事件回调)请注意,这里我们有一种“循环依赖关系”,即“当
zoomLevel
更改时执行某些操作( map 上的setZoom)”和“当某件事(用户更改缩放)时更改zoomLevel
”。我想要一个可以避免这种循环观察者依赖性的解决方案。 Ember的notifyPropertyChange可能是一个解决方案。对于Ember's computed properties来说,这似乎是一项理想的任务,但我不知道在依赖属性字符串中应放置什么内容。
zoomLevel
基本上是一个属性,该属性依赖于不是ember属性的内容。更新资料
我的第一次尝试是使用观察者在传单上设置缩放并在传单
zoomend
上绑定(bind)一个事件以在我的 View 上设置zoomLevel
。问题:在zoomend传单事件上设置zoomLevel时,我会自动再次触发观察者。我说清楚了吗?
因此,事件的顺序发生了:
zoomLevel
zoomend
事件zoomend
事件回调集 Ember zoomLevel
setZoom
这效率不高,但是我不介意它是否有效。
问题在于,当用户非常快速地多次更改缩放比例(在 map 上进行简单的长滚动)时,观察者被多次调用confusing leaflet。
最佳答案
好吧,我想我已经做到了。
我使用了计算属性和辅助属性。
App.Leaflet = Ember.View.extend({
classNames : ['ember-leaflet'],
//default zoom level
zoomLevelValue : 13,
zoomLevel : function(key, value){
// getter
if (arguments.length === 1) {
var zoomLevel = this.get('zoomLevelValue');
return zoomLevel;
// setter
} else{
var map = this.get('map');
this.set('zoomLevelValue', value);
map.setZoom(value);
return value;
}
}.property('zoomLevelValue'),
didInsertElement : function() {
var self = this;
var zoomLevel = this.get('zoomLevel');
var map = L.map(this.$().get(0)).setView(center, zoomLevel);
// configure map instance...
// Event listeners
map.on('zoomend', function(e) {
console.log('zoomend', 'Setting zoomLevel '+e.target.getZoom());
self.set('zoomLevelValue', e.target.getZoom());
});
// save map instance
this.set('map', map);
}
});
基本上有两种情况:
但是我有一个新问题,但是我认为这与传单有关。当我在另一个缩放动画进行过程中调用
setZoom
时,将忽略此setZoom。例如,执行:
map.setZoom(1);
map.setZoom(12);
最终达到
1
缩放级别。也许与传单相关的SO问题可以提供帮助。