管理領域にマップする
私の仕事は、Grouponの提案を領土に分割し、管理者が編集できるようにすることでした。 エリアからのオファーは、他のエリアからのオファーより優先順位が高いこれらのエリアに住んでいる人々に表示されます。
管理パネルで、Yandex.Mapsに基づくインタラクティブマップを作成し、その上にオファーのポイントとエリアを表示することにしました。 エリアは追加および編集でき、その座標はデータベースに保存されます。 Yandex.Mapsは、マップ上にさまざまな要素を描画するための広範なAPIを提供します。そこからポリゴンが出てきて、文章のツールチップでエリアとポイントを表示しました。 以下のスクリーンショットは、提供ポイント、おそらく秘密の情報なしで;)
いくつかのデータモデルを作成しました。都市の領土の本質を記述するCityArea、CityAreaを構成するポイントの座標を格納するCityAreaPoint、およびAreaOffer-提案は特定の領域に属します。 ページ、描画エリア用のJS、オブジェクトを相互にリンクするためのサーバーロジック、およびページへのデータの出力に関する質問が用意されました。 MVCの標準的な方法の1つは、コントローラーアクションで必要なデータを選択し、必要な形式に編集し、変数に最終データ配列を書き込み、このデータが書き込まれ、JSが読み取られるデータ属性を持つ要素を追加することですああ。 つまり、私はこのようなことをしました:
app/controllers/admin/map_controller.rb
@location = City.find(params[:city_id].to_i) @offers = Offer.sorted.by_city(@location).by_day(params[:date]) @offers.map! do |offer| points = offer.points.map do |point| { id: it.id, longitude: it.longitude, latitude: it.latitude } end { id: offer.id, permalink: offer.permalink, title: offer.short_title, points: points } end @city_areas = CityArea.find_by_city @location @city_areas.map! do |area| # end
app/views/admin/map/map.html.haml
.data-container{ data: { areas: @city_areas.to_json, offers: @offers.to_json } }
app/assets/javascripts/admin/map.js
$('.data-container').data('offers') ...
結果は非常にビジーなコントローラーでした-そこにあるべきではないコードが多すぎます。 それをモデルに入れることができますが、コードはまだこのようなもののままです。 rablおよびjbuilderテンプレートをサポートするgem gonを使用することにしました。 Rablは、オブジェクトのコレクションやデータベースオブジェクトの関連付けに最適な優れたGemであるため、テンプレート内のコードはより最適です。 gonを使用すると、rablのパワーを簡単かつ簡単に使用できます。
app/controllers/admin/map_controller.rb
@location = City.find(params[:city_id].to_i) @offers = Offer.sorted.by_city(@location).by_day(params[:date]) @city_areas = CityArea.find_by_city @location gon.rabl template: 'app/rabl/offers.json.rabl', as: 'offers' gon.rabl template: 'app/rabl/areas.json.rabl', as: 'areas'
app/rabl/offers.json.rabl
collection @offers => 'offers' attributes :id, :permalink, :short_title child :points do attributes :id, :latitude, :longitude end
app/assets/javascripts/admin/map.js
gon.offers …
したがって、データの変換とこのデータのJSへのスローに最小限の労力を費やして、「クリーン」なコントローラーと、JSに必要なデータの配列を取得しました。
ゴンジェム
rablおよびjbuilderテンプレートでの作業に加えて、gonはプロジェクトのどこからでも設定でき、プロジェクトのどこからでもアクセスできる初期データまたはグローバルデータを表示するのに最適です。 つまり、たとえば、ある変数の値がプロジェクトのすべてのページにある場合は、この変数を初期化子で設定するだけで十分です。 これを行うには、 gon.globalメソッドを使用します。これは、gonに書き込まれる変数のスコープがグローバルであることを除いて、gonと同様に機能します。 JSでは、変数はgon.global名前空間を介してアクセスできます。
さらに、昨日、バージョン4.0.0をリリースしました。このバージョンでは、ページをリロードせずに変数のデータを更新する機能-gon.watchが登場しました 。 新しい機能を使用すると、イベントに応じて、n秒間隔のサイクルと1回限りの両方でデータを更新できます。 例として、コードの数行でtopコマンドの結果をリアルタイムで表示する方法を示します。
新しいRailsアプリケーションがあるとします。 ターミナルトップを表示するには、次の操作を行うだけです。
1.
gem 'gon'
行をGemfileに追加し、
bundle install
を実行します
2.アクションを使用してコントローラーを追加します。たとえば、home#foo、
app/views/home/foo.html.erb
とJS
app/assets/javascripts/home.js.coffee
rails g controller home foo
3.コントローラーアクション
app/controllers/home_controller.rb
で、トップコマンドの1回限りの実行を
app/controllers/home_controller.rb
書き込みます。
def foo gon.watch.top = `top -l1` end
4.レイアウト
app/views/layouts/application.html.erb
で、監視オプションを頭に持つヘルパーを追加します。
<head> <%= include_gon(watch: true) %>
5.
app/views/home/foo.html.erb
topが表示されるタグを追加します。
<pre style='font-family:monospace;'></pre>
6.コーヒーファイルで、変数に従うコードを追加し、preタグの内容を更新します。
$(document).ready -> renewPre = (data) -> $('pre').html(data.replace(/\\n/, "\n")) gon.watch('top', interval: 1000, renewPre)
gon.watch
は2つまたは3つのパラメーターを受け入れます-変数の名前、オプション(オプション)、コールバック。 この場合、
interval: 1000
オプションを渡しました。これは、gon.watchコードを1秒ごとにループします。 これは、
gon.watch
が1秒
gon.watch
変数が割り当てられたコントローラーのアクションにリクエストを送信し、現在の値を返すことを意味します。リクエストが正常に完了すると、コールバックが呼び出され、次にpreタグの内容が書き換えられます。 ループを停止するために、変数名とコールバック関数としてパラメーターを受け取るgon.unwatch関数があります。 当然、
interval
オプションを渡さない場合、サイクルは発生せず、1回限りの要求が発生し、成功した場合は1回限りのコールバック呼び出しが発生します。
それだけです
0.0.0.0:3000/foo
実行し、
0.0.0.0:3000/foo
開きます-そこにライブがあります。