1

このトピックに関する多くの質問を見てきましたが、決定的な解決策はありません。ERB/slim と Coffeescript/EJS/Backbone を活用する Rails 3.2 アプリがあります。私はこのコードベースを継承したので、これらの周辺機器のいくつかは私の頭を少し超えています。

問題

私のビューには、に送信されvenueたセクションが表示されます。のリストには、JavaScript による「並べ替え」機能があります。関連する CoffeeScript ファイルには、「最近」および「人気」のリンクをクリックするためのイベント リスナーがあります。クリックすると、JS はいくつかの作業を行い、Rails スコープを利用してリストを並べ替えます。Rails helper を含め、もう少しデータを含めるためにこのリストを作成しています。元のコードは、Javascripts/templates アセット ディレクトリの JST/EJS テンプレートを使用して、ヒントを含む div を更新しました。tipsvenuetipstipstime_ago_in_words

これらは私が遭遇する特定の問題です:

  1. ファイル チェーンに .erb を追加すると (ERB と競合しないように EJS インタープリターを更新して別の評価および補間パターンを探した後)、基本的な Ruby 式を評価できます。tipただし、パーシャルは、JavaScript が参照する同じ変数にアクセスできません。これは、Rails がサーバー側で JS がクライアント側であるためです。コンセンサスはノーのようですが、そのデータをRailsに送る方法はありますか?
  2. 基本的な Ruby 式は評価できますが (Time.nowたとえば、Rails ヘルパーはtime_ago_in_words失敗し、メソッドがクラスに対して未定義であると不平を言いますが、適切な日付オブジェクトを絶対に渡しています。Rails/ヘルパーは、この .EJS.ERB チェーンで評価できませんか?
  3. ソートの実行後にロード時に使用される元の ERB/slim パーシャルを参照する方法があれば、これらの問題をすべて回避できます。これは可能ですか?現在、Coffeescript と呼ばれるファイルは、EJS テンプレートを使用renderして呼び出します。JSTどうにかして元のパーシャルを参照することは可能ですが、更新された並べ替えを使用することはできますか?

関連するコードは次のとおりです。

  ##show.html.erb (venue)##
  #tips
    p.sort.span4
      | Sort by: 
      = link_to 'Recent', '#', class: 'selected', id: 'sort-tips-recent'
      |  | 
      = link_to 'Popularity', '#', id: 'sort-tips-popularity'
    #tip-list
      = render resource.tips.by_recent


##tip_list_view.js.coffee##
class CS.TipListView extends Backbone.View
  el: "#tip_module"

  events:
    "click #sort-tips-recent": "sortByRecent"
    "click #sort-tips-popularity": "sortByPopularity"

  initialize: ->
    console.log("ERROR: View must be initialized with a model") unless @model
    @model.bind('reset', @render)

  render: =>
    tips = @model.map (tip) -> JST['templates/tip'](tip: tip)
    @$('#tip-list').html(tips.join("\n"))

  sortByRecent: (e) ->
    e.preventDefault()
    @model.enableSortRecent()
    @updateSelectedFilter('recent')

  sortByPopularity: (e) ->
    e.preventDefault()
    @model.enableSortPopularity()
    @updateSelectedFilter('popularity')

  updateSelectedFilter: (sort) ->
    @$('p.sort a').removeClass('selected')
   @$("p.sort a#sort-tips-#{sort}").addClass('selected')


##tip.jst.ejs.erb (called from tip_list_view.js.coffee after sort change##
<div class="tip">
  <p class="tip-author">
    <$= tip.get('user').username $>
  </p>
  <p class="tip-timestamp">
    Eventually, time goes here
  </p>
  <p class="tip-likes pull-right">
    <$= tip.upvoteCountText() $>
  </p>
  <p id="<$= tip.domId() $>">
    <$= tip.get('text') $>
    <$ if(tip.get('can_upvote')) { $>
      <a href="<$= tip.upvoteUrl() $>">upvote</a>
    <$ } $>
  </p>
<div>

ここで間違いなく途方に暮れています-あらゆる助けが大歓迎です。背景として提供できるその他の詳細やコードがあれば教えてください。前もって感謝します!

4

1 に答える 1

1

Rails は ejs.erb を使用してテンプレートを生成していますが、それを何に使用するかはわかりません。次に、Backbone アプリが ajax を介して Rails からヒントを取得し、それに応じてモデルを設定します。次に、テンプレートを入力してレンダリングするのはバックボーン アプリです。Rails は、少なくともバックボーンが json を期待してからテンプレートをレンダリングするこの構成では、ここでチャイムを鳴らすことはできません。すべてがフロントエンドで行われています。

あなたができる唯一のことは、JSON 内のヘルパーの結果を提供するように Rails に依頼することです。Tip.rb モデルがあり、実装する必要があると思います。

include ActionView::Helpers::DateHelper
...
def as_json(options = {})
  {
    :name => self.name,
    ... (all the model attributes that you want to expose)
    :date_age => time_ago_in_words self.created_at
  }
end

そうは言っても、クライアント側のソリューションを使用することは間違いありません

于 2012-11-27T23:26:49.740 に答える