如何创建依赖于正常变量,函数或逻辑的余烬属性? [英] How to create an ember property dependent on a normal variable, function or logic?

查看:129
本文介绍了如何创建依赖于正常变量,函数或逻辑的余烬属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理emberjs的传单视图,我有一些问题。传单是一个外部图书馆,与问题无关,但只知道它是一个映射库。

I'm working on a leaflet view for emberjs, and I'm having some problems. Leaflet is an external library and somewhat irrelevant to the question, but just know that it is a mapping library.

考虑一个简单的属性,如缩放级别。传单地图实例通过 map.getZoom()可以通过 map.setZoom(zoomLevel)指定缩放级别。此外,用户可以与地图进行交互,并改变其缩放级别。传单允许我们在缩放更改时注册回调

Consider a simple property like zoom level. Leaflet map instances have a zoom level accessible through map.getZoom() and assignable through map.setZoom(zoomLevel). Also, users can interact with the map, and change its zoom level. Leaflet allows us to register a callback when the zoom changes.

我希望我的Ember-Leaflet视图具有一个 zoomLevel ember属性。这样,我可以从ember对象模型(例如绑定 zoomLevel 到一个模板或另一个值)中受益,我们正在做这个ember方式。

I would like my "Ember-Leaflet" View to have a zoomLevel ember property. This way I can benefit from the ember object model (bind zoomLevel to a template or to another value, for example), and we're doing it "the ember way".

我目前拥有的是Ember.View的子类,具有zoomLevel属性。在 didInsertElement 我创建了Leaflet地图实例。代码被评论,应该是不言自明的。

What I currently have is a subclass of Ember.View, with a zoomLevel property. On didInsertElement I create the Leaflet map instance. The code is commented and should be self-explanatory.

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);
    }
});



清单



我认为这个问题的解决方案应该满足以下要求:

Checklist

To make this question more "answerable", I think that a solution to this problem should fulfill the following requirements:


  1. 当属性 zoomLevel 已更改,地图应相应更改其缩放级别(使用 map.setZoom(zoomLevel)

  2. 当用户交互地更改地图上的缩放时,应该更改 zoomLevel 属性(可能使用传单地图的缩放事件回调)

  1. When the property zoomLevel is changed, the map should change its zoom level accordingly (using map.setZoom(zoomLevel))
  2. When the user interactively changes the zoom on the map, the zoomLevel property should be changed (probably using leaflet map's zoomend event callback)

请注意,我们在这里有一种循环依赖,即做一些(setZoom在地图上)当发生某些事情(用户更改缩放)时 zoomLevel 更改,更改 zoomLevel 的。我想要一个可以避免这种循环观察者依赖性的解决方案。 Ember的 notifyPropertyChange 可能是一个解决方案。

Notice that we have here a kind of "circular dependency", i.e "Do something (setZoom on map) when zoomLevel changes" and "when something happens (user changes zoom), change zoomLevel". I would like a solution that could avoid this circular observer dependencies. Ember's notifyPropertyChange could be a solution.

这似乎是一个理想的任务, Ember的计算属性,但是我不知道放在依赖属性字符串中的内容。 zoomLevel 基本上是一种依赖于不是ember属性的属性。

This seemed like an ideal task for Ember's computed properties, but I didn't know what to put in the dependent properties string. zoomLevel is basically a property that is dependent on something that isn't an ember property.

我的第一个尝试是使用观察器设置小册子上的缩放,并在传单上绑定一个事件缩放可以在我的视图中设置 zoomLevel

My first attempt was to use an observer to set the zoom on leaflet and to bind an event on leaflet zoomend to set the zoomLevel on my view.

问题:当我设置zoomLevel在zoomend传单事件中,我自动再次触发我的观察者。我明白了吗?

Problem: When I set zoomLevel on the zoomend leaflet event, I'm automatically triggering again my observer. Did I make myself clear?

所以,这一连串的事件发生了:

So, this sequence of events happen:


  1. c c> c c c c c >
  2. zoomend 事件回调设置ember zoomLevel

  3. 观察员运行

  4. 在传单上不必要地调用 setZoom
  1. change zoomLevel on interactive map
  2. leaflet fires zoomend event
  3. zoomend event callback sets ember zoomLevel
  4. observer runs
  5. unecessarily calls setZoom on leaflet

这不是有效的,但我不会介意,如果它有效。
问题是当用户非常快速地变换缩放倍数(地图上简单的长滚动)时,观察者被多次调用,混乱传单

This is not efficient, but I wouldn't mind if it worked. The problem is that when the user changes zoom multiple times very quickly (a simple long scroll on map) the observer is called multiple times, confusing leaflet.

推荐答案

好的,我想我已经做了。

Ok, I think I've did it.

我使用了一个计算的属性和一个辅助属性。

I used a computed property and an auxiliary property.

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);

    }
});

基本上有两种情况:


  1. zoomLevel已被程序更改 - >我们更新地图上的缩放

  2. zoomLevel已在地图上更改 - >我们设置在辅助属性上,而计算机财产观察员也会收到通知,我们还没有在地图上再次设置缩放级别

但是我有一个新问题,但我认为这是传单相关的。当我调用另一个缩放动画时,调用 setZoom ,这个setZoom被忽略。
例如,执行:

However I have a new problem, but I think it is leaflet related. When I call setZoom when another zoom animation on course, this setZoom is ignored. For example, executing:

map.setZoom(1);
map.setZoom(12);

最终在 1 缩放级别。

也许有关传单相关的SO问题可以帮助。

Maybe a leaflet related SO question can help.

这篇关于如何创建依赖于正常变量,函数或逻辑的余烬属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆