缓慢的Ember计算属性

时间:2018-05-16 01:21:07

标签: ember.js ember-data

我在我的模型中构建了一个计算属性,使用用户位置和兴趣点位置(在本例中为葡萄园)运行距离位置的计算。计算似乎需要一秒钟,即使尚未设置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();
    });
  })
});

1 个答案:

答案 0 :(得分:2)

有些事情很突出......

您的计算属性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将因用户而异(我看到您在进行此操作时有一个硬编码的用户位置)。因此,您可能希望将此计算属性移出模型并进入组件或控制器。因此,在您的组件或控制器中,您将拥有:

milesAway: computed('model.location', function() {
    let location = this.get('model.location');

    // Your code to calculate the distance

    return distance;  
})