如何创建余烬属性依赖于一个正常的变量,函数或逻辑?(How to create an ember p

2019-08-18 01:26发布

问题

我正在为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);
    }
});

清单

为了使这个问题更加“交代”,我认为,这个问题的解决方案应满足以下要求:

  1. 当财产zoomLevel发生变化,则应该相应地改变其缩放级别(使用map.setZoom(zoomLevel)
  2. 当用户以交互方式改变地图上的变焦时, zoomLevel属性应该(可能使用单张地图的改变zoomend事件回调)

请注意,我们这里有一种“循环依赖”,即“做什么(在地图上setZoom)当zoomLevel变化”“有事时(用户改变缩放),改zoomLevel ”。 我想,可能避免这种圆形观测依赖的解决方案。 Ember的notifyPropertyChange可能是一个解决方案。

这似乎是一个理想的工作Ember的计算性能 ,但我不知道要放什么东西在从属属性字符串。 zoomLevel基本上是依赖于东西是不是余烬属性的属性。


更新

我第一次尝试使用一个观察者设置单张变焦,并在传单事件绑定zoomend设置zoomLevel对我的看法。

问题:当我设置个zoomLevel在zoomend传单时,我会再次自动触发我的观察者。 难道我讲得清楚吗?

因此,这一系列事件发生:

  1. zoomLevel互动地图上
  2. 单张火灾zoomend事件
  3. zoomend事件回调设置烬zoomLevel
  4. 观察者运行
  5. unecessarily呼吁setZoom的传单

这是效率不高,但我不介意它的工作。 问题是,当用户改变放大多次非常迅速(一个简单的长卷上图)的观察员被多次调用, 混淆传单 。

Answer 1:

好吧,我想我已经做到了。

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

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被忽略。 例如,执行:

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

在结束了1缩放级别。

也许相关的小册子SO问题可以提供帮助。



Answer 2:

从个zoomLevel获得烬到setZoom你可以使用一个观察者。

为了走另外一条路,你可能需要绑定一个事件zoomChange的传单



Answer 3:

很少不同的策略,我做了个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: '&copy; <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?