防止方法在Meteor中的服务器上自动运行

时间:2017-10-02 04:18:26

标签: javascript meteor coffeescript geocoding

我试图在服务器文件夹中创建一个地理编码方法,但它抱怨该地址未在页面加载时定义。看起来该方法在输入具有值(或已被调用)之前触发页面加载并导致此行为。有没有办法让方法等到运行,直到被调用而不是自动运行,或者另一种方法绕过这个问题? Aldeed:地理编码器似乎只运行服务器端。

我的coffeescript方法,使用aldeed:geocoder

geocodeAddress: (address) ->
lat = ''
lng = ''
    addressVar = ''
    geocoder = new GeoCoder(
      geocoderProvider: 'google'
      httpAdapter: 'https'
      apiKey: 'AIzaSyDYjLGrETRt4hPZtXcmzQwRbzlFT1zWwr8')
    geocoder.geocode { 'address': address }, (results, status) ->
        if status == google.maps.GeocoderStatus.OK
          lat = results[0].geometry.location.lat()
          lng = results[0].geometry.location.lng()
            return [lat,lng]

模板事件

Template.dashboard.events({
  'click #customlocationsubmit'(evt) {
    if (document.getElementById("customlocation")) {
      customLocationValue = document.getElementById("customlocation").value;
    }
    if (typeof customLocationValue === 'undefined' || customLocationValue == "") {
        return false;
    } else {
    customUserLocation = Meteor.call('geocodeAddress',customLocationValue);
  }
  }
});

模板

<template name="dashboard">
    <div class="template-dashboard">
        <div class="container">
            <div class="row">
                <div class="col-md-3">
                    {{> addPost}}
                    {{> favoritesSidebar}}
                </div>
                <div class="col-md-9">
                <button id="customlocationsubmit" type="submit" class="btn btn-primary">Update</button>

                    {{> posts}}
                </div>
            </div>
        </div>
    </div>
</template>

再次更新Styx的点击事件

'click #customlocationsubmit'(evt) {
    if (document.getElementById("customlocation")) {
      customLocationValue = document.getElementById("customlocation").value;
    }
    if (typeof customLocationValue === 'undefined' || customLocationValue == "") {
        return false;
    } else {
    Meteor.call('geocodeAddress', customLocationValue, (err, result) => {
    if (err) {
      // handle error
      return;
    }
    const [ lat, lng ] = result;
    geoResult = result;
    const sortOrder = (Session.get('posts.sortBy') || {}).date || 1;
    return Session.set('posts.sortBy', {date: -sortOrder});
    return distanceFilter(this, geoResult );
  });
  }

  },

styx的辅助函数

distanceFilter(location,customUserLocation) {
    function getDistanceFromLatLonInMi(lat1,lon1,lat2,lon2) {
      var R = 6371; // Radius of the earth in km
      var dLat = deg2rad(lat2-lat1);  // deg2rad below
      var dLon = deg2rad(lon2-lon1);
      var a =
        Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
        Math.sin(dLon/2) * Math.sin(dLon/2)
        ;
      var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
      var d = R * c; // Distance in km
      var e = d * 0.621371;
      return e;
    };

    function deg2rad(deg) {
      return deg * (Math.PI/180);
    };

    getUser = Meteor.users.findOne({
      _id: Meteor.userId()
    });
    if (getUser){
    userUserName = getUser.username;
    userLocation = getUser.profile.location.split(',');
    };
    eventLocation = location.split(',');
    if (typeof customLocationValue === 'undefined' || customLocationValue == "") {
      customUserLocationVar = userLocation;
    }
      else {
        customUserLocationVar = customUserLocation;
        console.log(customUserLocation);
      }
    distance = getDistanceFromLatLonInMi(customUserLocationVar[0],customUserLocationVar[1],eventLocation[0],eventLocation[1]);
    eventDistance = Math.round(distance);
    filterValue = jQuery('#eventdistance').val();
    if (filterValue) {
      if (eventDistance <= filterValue) {
        return true;
        }
    } else if (eventDistance <= 20) {
          return true;
    } else {
          return false;
    }

  },

1 个答案:

答案 0 :(得分:1)

使用aldeed:geocoder Meteor软件包(以及另一个问题)存在两个问题:

  1. 来自package documentation

      

    对地址进行地理编码很简单。获取GeoCoder的新实例,然后在其上调用地理编码方法,传入地址字符串。

    这意味着,与npm包不同,geocode()函数需要第一个参数为字符串 - 您想要进行地理编码的地址(source code

  2. 来自同一文档:

      

    请注意,与节点包不同,地理编码方法是同步。这使得在服务器方法中使用变得简单。如果您希望将回调作为最后一个参数传递,则可以。

    这意味着,您的服务器方法可以(并且应该)利用它:

    geocodeAddress: (address) ->
      geocoder = new GeoCoder
        httpAdapter: 'https'
        apiKey: 'AIzaSyDYjLGrETRt4hPZtXcmzQwRbzlFT1zWwr8'
    
      result = geocoder.geocode(address).pop()
    
      [ result.latitude, result.longitude ]
    
  3. 正如Michel Floyd在评论中已经指出的那样,客户端上的Meteor.call异步,所以你应该这样做:

    Meteor.call('geocodeAddress', customLocationValue, (err, result) => {
      if (err) {
        // handle error
        return;
      }
      const [ lat, lng ] = result;
      // handle success
    });
    
  4. 已添加:来自geocode(address)的回复(从meteor shell执行):

    > g.geocode('02068, Ukraine, Kiev')
    [ { formattedAddress: 'Kiev, Ukraine, 02000',
        latitude: 50.4501,
        longitude: 30.5234,
        extra: 
         { googlePlaceId: 'ChIJBUVa4U7P1EARxX1LbAvqE6A',
           confidence: 0.5,
           premise: null,
           subpremise: null,
           neighborhood: null,
           establishment: null },
        administrativeLevels: { level2long: 'Kyiv City', level2short: 'Kyiv City' },
        zipcode: '02000',
        city: 'Kiev',
        country: 'Ukraine',
        countryCode: 'UA' } ]