问题
我正在为emberjs的单张视图,我有一些问题。 传单是一种外部库,有点风马牛不相及的问题,但我们知道,这是一个映射库。
考虑一个简单的属性,如缩放级别。 单张地图实例必须通过访问一个缩放级别map.getZoom()
和分配通过map.setZoom(zoomLevel)
此外,用户可以与地图交互,并改变其缩放级别。 单张允许我们注册一个回调变焦变化时。
我想我的“余烬,传单”查看到有zoomLevel
烬特性。 这样我可以从灰烬对象模型中获益(绑定zoomLevel
到模板或其他值,例如),和我们正在做“余烬方式”。
基本的解决方案
我现在已经是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
事件回调)
请注意,我们这里有一种“循环依赖”,即“做什么(在地图上setZoom)当zoomLevel
变化”和“有事时(用户改变缩放),改zoomLevel
”。 我想,可能避免这种圆形观测依赖的解决方案。 Ember的notifyPropertyChange可能是一个解决方案。
这似乎是一个理想的工作Ember的计算性能 ,但我不知道要放什么东西在从属属性字符串。 zoomLevel
基本上是依赖于东西是不是余烬属性的属性。
更新
我第一次尝试使用一个观察者设置单张变焦,并在传单事件绑定zoomend
设置zoomLevel
对我的看法。
问题:当我设置个zoomLevel在zoomend传单时,我会再次自动触发我的观察者。 难道我讲得清楚吗?
因此,这一系列事件发生:
- 改
zoomLevel
互动地图上 - 单张火灾
zoomend
事件 -
zoomend
事件回调设置烬zoomLevel
- 观察者运行
- unecessarily呼吁
setZoom
的传单
这是效率不高,但我不介意它的工作。 问题是,当用户改变放大多次非常迅速(一个简单的长卷上图)的观察员被多次调用, 混淆传单 。
好吧,我想我已经做到了。
我用一个计算属性和辅助属性。
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);
}
});
基本上有两种情况:
- 个zoomLevel被编程改变 - >我们更新了地图上的变焦
- 个zoomLevel改为在地图上 - >我们的辅助属性设置,并且计算机性能观察员也将得到通知,我们没有再在地图上设置缩放级别
但是我有一个新的问题,但我认为这是小叶相关。 当我打电话setZoom
当上当然另一个缩放动画,这setZoom被忽略。 例如,执行:
map.setZoom(1);
map.setZoom(12);
在结束了1
缩放级别。
也许相关的小册子SO问题可以提供帮助。
从个zoomLevel获得烬到setZoom你可以使用一个观察者。
为了走另外一条路,你可能需要绑定一个事件zoomChange的传单
很少不同的策略,我做了个zoomLevel的属性和功能观察它,只有在地图上设置的变焦如果财产的实际值与实际的变焦不同。 看到这个小提琴http://jsfiddle.net/5As2z/30/我通过逻辑的控制器,所述视图在地图设定在文件插入时
App.ApplicationController = Ember.Controller.extend({
//default zoom level
zoomLevel: 13,
map: null,
zoomLevelChanged: function () {
var zoomLevel = this.get('zoomLevel');
var map = this.get('map');
//Control not changing the zoom of the map if it is yet at the value
if (zoomLevel != map.getZoom()) {
map.setZoom(zoomLevel);
}
}.observes('zoomLevel')});
App.ApplicationView = Ember.View.extend({
templateName: 'application',
didInsertElement: function () {
var center = [41.3823000, 2.1825000];
var controller = this.get('controller');
var zoomLevel = controller.get('zoomLevel');
var map = L.map('map').setView(center, zoomLevel);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// configure map instance...
// Event listeners
map.on('zoomend', function (e) {
console.log('zoomend', 'Setting zoomLevel ' + e.target.getZoom());
controller.set('zoomLevel', e.target.getZoom());
});
// save map instance
this.controller.set('map', map);
}});
HTML
<script type="text/x-handlebars" data-template-name="application">
<h1> Leaflet map ember example </h1>
{{view Ember.TextField valueBinding="zoomLevel"}}
<div id="map"></div >
</script>
文章来源: How to create an ember property dependent on a normal variable, function or logic?