【问题标题】:Slow Ember Computed Property慢 Ember 计算属性
【发布时间】:2018-05-16 01:21:07
【问题描述】:

我在我的模型中构建了一个计算属性,以使用用户位置和兴趣点位置(在本例中为葡萄园)计算到某个位置的距离。计算似乎需要一秒钟,即使没有设置 milesAway 属性,模板也会呈现。从而无法呈现相关信息。有任何想法吗?型号代码如下...

import DS from 'ember-data';
import attr from 'ember-data/attr';
import { belongsTo, hasMany } from 'ember-data/relationships';
import EmberObject, { computed, observer } from '@ember/object';
import { inject as service } from '@ember/service';

export default DS.Model.extend({
  featuredImages: hasMany('contentful-asset'),
  featured: attr('boolean'),
  name: attr('string'),
  slug: attr('string'),
  rating: attr('number'),
  location: attr('string'),
  latitude: attr('string'),
  longitude: attr('string'),
  bodyOne: attr('string'),
  milesAway: attr('string', {async: false}),
  googleMapsApi: Ember.inject.service(),
  googleLocation: computed(function() {
    let userLocation = 'Hard Coded Test Address';
    let endLocation = this.get('location');
    let milesAway = '';
    let googleMapsApi = this.get('googleMapsApi');
    this.get('googleMapsApi.google').then((google) => {
      var self = this;
      let distanceMatrixService = new google.maps.DistanceMatrixService();
      function calculateDistance() {
        distanceMatrixService.getDistanceMatrix({
          origins: [userLocation],
          destinations: [endLocation],
          travelMode: google.maps.TravelMode.DRIVING,
          unitSystem: google.maps.UnitSystem.IMPERIAL,
          avoidHighways: false,
          avoidTolls: false
        }, callback);
      }
      function callback(response, status) {
        if (status != google.maps.DistanceMatrixStatus.OK) {
          self.toggleProperty('errorState');
        } else {
          if (response.rows[0].elements[0].status === "ZERO_RESULTS") {
            self.toggleProperty('errorState');
          } else {
            var distance = response.rows[0].elements[0].distance;
            var distance_text = distance.text;
            self.set('milesAway', distance_text);
          }
        }
      }
      calculateDistance();
    });
  })
});

【问题讨论】:

    标签: ember.js ember-data


    【解决方案1】:

    有几件事很突出......

    您的计算属性googleLocation 缺少它的依赖项,这将阻止它被更新。至少应该列出location。

    此外,计算属性是“纯函数”,因此无论何时执行它们都没有副作用。因此,与其在计算函数中设置milesAway,不如从计算函数返回一个值,也可以将其命名为milesAway。我不能对距离计算部分发表太多评论,因为我自己还没有这样做。

    你应该从你的代码中删除这一行:

    milesAway: attr('string', {async: false}),
    

    并执行类似以下结构的操作:

    milesAway: computed('location', function() {
        let location = this.get('location');
    
        // Your code to calculate the distance
    
        return distance;  
    })
    

    但是,模型本质上是为持久数据而不是瞬态应用程序数据而设计的。对于使用此模型的每个葡萄园,milesAway 会因用户而异(我看到您在处理此问题时有一个硬编码的 userLocation)。因此,您可能希望将此计算属性移出模型并移入组件或控制器中。因此,在您的组件或控制器中,您将拥有:

    milesAway: computed('model.location', function() {
        let location = this.get('model.location');
    
        // Your code to calculate the distance
    
        return distance;  
    })
    

    【讨论】:

    • 这是有道理的。你能给我一些关于如何将它放入组件/控制器并更新所有模型属性的指导吗?
    • @ChrisJohnson 我创建了一个 Ember Twiddle 来说明如何为 vineyard 路由:ember-twiddle.com/… 完成此操作。注意:Ember Twiddle 不支持 Ember 3 的某些语法导入,所以代码有点过时,但它显示了整体结构。
    • 谢谢 casfred,这看起来很棒。如果每个葡萄园的价值不同,我该如何设置?
    • @ChrisJohnson 在实际情况下,您的葡萄园路线将被传递一个vineyard_id 参数,然后它将用于从商店中获取葡萄园并设置为模型。我在 twiddle 中添加了一些进一步的 cmets,显示你在你的情况下会做什么。此外,如果您最近没有这样做,Ember 教程“超级租赁”(guides.emberjs.com/v3.1.0/tutorial/ember-cli) 涵盖了您正在尝试做的一些事情,并且可能会为您自己解决一些问题省去一些麻烦。跨度>
    • @ChrisJohnson 要实现列表视图,您很可能会使用一个组件来显示每个模型实例并执行计算功能。我已经调整了 Twiddle 来说明它的样子。最后一个想法,Super Rentals 说明了服务如何结合缓存,这是您在使用 GoogleAPI 和计算时可能需要考虑的事情(在您拥有基本版本之后 :-))。
    猜你喜欢
    • 1970-01-01
    • 2016-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-20
    • 2014-05-26
    • 2014-03-01
    • 2014-07-09
    相关资源
    最近更新 更多