2016-06-18 9 views
0

ここにJS noobがあります。ng-repeatで非同期ジオロケーション値を使用するにはどうすればよいですか?

私は周りのレストランを一覧表示するアプリを作成しようとしています。私のビューの1つは、各レストランについて、現在の場所とそのレストランの距離を表示することになっています。私は各レストランの計算を実行し、その値をビューに表示する問題があります。

私の現在のコードでは、ページの上部が読み込まれ、呼び出し先の関数(distanceToPlace)がすべての場所で呼び出され、ロードが完了し、最後に正しい距離値を持つ要素が表示されます。

は複数の問題があります:ジオロケーションAPIを一度レストランあたりより多く呼び出さ

  • 、私は理解できない理由(私は、デシベルで50軒のレストランがあり、時々私は私のコンソールログの確認を参照してくださいprint 2000+ times)

  • レストランごとに1回だけ呼び出されたとしても、実際には効率的ではありません。ページが読み込まれたときに一度呼び出す方法があり、各レストランのデータで距離計算を行うだけです。さらに、私のアプリ全体には、どのページからでもアクセスできるユーザーの場所(X秒ごとに更新)を含む何らかの種類のグローバル変数が必要です。

さらに私は計算が行われた後の距離でレストランを並べ替えできるようにしたいと思いますが、私はここに、この:(

について移動する方法を見当もつかないが、JSが内側に(ではない持っていますコントローラ):

 var userLng = ''; 
 
     var userLat = ''; 
 
     this.loaded = false; 
 
     var that = this; 
 

 
     //Calculate the distance with coordinates 
 
     function getDistanceFromLatLonInKm(lon1,lat1,lon2,lat2) { 
 
      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 
 
      return d; 
 
     } 
 

 
     //Calculation sub-formula 
 
     function deg2rad(deg) { 
 
      return deg * (Math.PI/180) 
 
     } 
 

 
     //Find user's location then start the distance calculation 
 
     this.distanceToPlace = function(placeLng, placeLat) { 
 
      navigator.geolocation.getCurrentPosition(function(position) { 
 
       userLng = Math.round(position.coords.longitude * 1000000)/1000000; 
 
       userLat = Math.round(position.coords.latitude * 1000000)/1000000; 
 
       that.loaded = true; 
 
       console.log('Done'); 
 
       return Math.round(getDistanceFromLatLonInKm(userLng, userLat, placeLng, placeLat) * 1000); 
 
      }); 
 
     };

そして、ここでは、ビューの:

私はそこに「NG-場合は」使用しますが、私はそれはそれを行うには正しい方法だ場合、かなりよく分からない

<md-content flex ng-show="placeSearch.loaded"> 
 
    <md-card ng-repeat="place in placeSearch.places | eventDayFilter:placeSearch.eventDay | placeAreaFilter:placeSearch.area | eventTimeFilter:placeSearch.eventTime:placeSearch.eventDay | orderBy:placeSearch.sort"> 
 
    <md-card-title> 
 
     <md-card-title-media> 
 
     <div class="md-media-md card-media"> 
 
      <img src="https://pbs.twimg.com/profile_images/611558188744372225/VoCVrXWX.png"> 
 
     </div> 
 
     </md-card-title-media> 
 
     <md-card-title-text> 
 
     <span class="md-subhead" ui-sref="placeDetails({ placeId: place._id, lastPage: 'search' })"> 
 
         {{place.name}} 
 
        </span> 
 
     <small>{{place.events[placeSearch.eventDay].begin}}h-{{place.events[placeSearch.eventDay].end}}h:</small> 
 
     <span class="md-body-1">{{place.events[placeSearch.eventDay].description}}</span> 
 
     <span flex></span> 
 
     <div layout="row" layout-align="space-between end"> 
 
      <span class="md-caption"> 
 
          <md-icon md-svg-icon="action:ic_room_24px"></md-icon> 
 
          <span ng-if="distance=placeSearch.distanceToPlace(place.address.lon, place.address.lat)">{{distance}} m</span> 
 
      </span> 
 
      <md-icon class="icon-fav" md-svg-icon="action:ic_favorite_border_24px"></md-icon> 
 
     </div> 
 
     </md-card-title-text> 
 
    </md-card-title> 
 
    </md-card> 
 
</md-content>

。 ありがとうございます!

+0

角度ダイジェストサイクルの仕組みが理解できません。アプローチはすべて間違っています。あなたが見たいものだけが実際の値です。すべての距離の計算は、ビューではなくコントローラで初期化する必要があります。一度ユーザーポジションを取得した後、コントローラのデータをループしてください – charlietfl

答えて

0

は、ここで私はこの問題にアプローチする方法をです:

  1. 私は出版物は、単一のパラメータ、ユーザーの現在の座標を持つオブジェクトを持っているでしょうレストラン
  2. のカーソルを返すパブリケーションを作成します
  3. 私はN秒ごとに1回以上実行しないようにします(ユーザが急速に動いている場合)
  4. Meteorはmongodb geoをサポートしていないため、クライアント側のクエリはサーバー上でのみ実行されます。
  5. 私は、クライアントからそのパブリケーションを購読して、ユーザーの現在の位置を渡します。
  6. 私はおそらく依然として距離計算をクライアント上で行い、そこでの並べ替えは、レストランオブジェクトの配列を返すヘルパーその距離のために余分なキーを付けてください。
  7. あなたの角度コードはレストランのオブジェクトを表示するだけで対処できます
  8. 上記のコードがすべて動作してデバッグされたら、背の高いものを楽しんでjs noobバッジを取り除くことができます。

それはソート・キーですので、それは個々のレストランのためのヘルパーで距離を計算しても意味がありません - あなたはレストランの全体リスト/配列を返すヘルパーでそれをやってみたいです。また、あなたが目撃したように、個々のヘルパーは予想よりも頻繁に動作します。

+0

詳細な回答ありがとうございます。私はポイント4-5と少し混乱しています。ジオロケーションクエリは「Meteor.publish」関数内で実行されるため、登録時にクライアントからのユーザーの現在位置(そのクエリで計算された)をどのように渡すことができますか? – MaxenceP

+0

クライアント上で現在の位置を取得していませんか?そうであれば、クライアント上で 'handle = Meteor.subscribe( 'nearbyRestaurants'、myLocation)'を実行し、サーバ上では 'Meteor.publish( 'nearbyRestaurants'、function(myLocation){})'を実行します。 –

関連する問題