首页 文章

在Ajax更新后,可以使用ERB / slim模板而不是EJS(JST)吗?

提问于
浏览
1

我已经看到围绕这个主题的很多问题,但没有明确的解决方案 . 我有一个利用ERB / slim和Coffeescript / EJS / Backbone的Rails 3.2应用程序 . 我继承了这个代码库,因此其中一些外围设备有点过头了 .

Problem

我的 venue 视图有一个显示 tips 的部分已提交给 venue . tips 的列表具有由JavaScript促成的"sort"功能 . 关联的CoffeeScript文件具有用于"recent"和"popular"的链接点击的事件侦听器 . 在单击时,JS执行一些工作并利用Rails范围来求助列表 . 我正在构建这个 tips 列表以包含更多的数据,特别是包括Rails助手 time_ago_in_words . 原始代码使用Javascripts / templates资产目录中的JST / EJS模板更新了包含提示的div .

这些是我遇到的具体问题:

  • 如果我将.erb添加到文件链中(在更新EJS解释器以寻找不与ERB冲突的不同评估和插值模式之后),我可以评估基本的Ruby表达式 . 但是,部分无法访问JavaScript引用的相同 tip 变量 . 我知道这是因为Rails是服务器端而JS是客户端 . 共识似乎不是,但有没有办法将数据传递给Rails?

  • 虽然可以评估基本的Ruby表达式(例如 Time.now ),但是Rails帮助程序如 time_ago_in_words 会失败,抱怨该类的方法未定义,尽管我绝对传递了正确的日期对象 . 可以在此.EJS.ERB链中评估Rails /帮助程序吗?

  • 如果有一种方法可以在执行排序后引用加载时使用的原始ERB / slim部分,我可以避免所有这些问题 . 这可能吗?现在,调用的Coffeescript文件使用 renderJST 来调用EJS模板 . 是否有可能以某种方式引用原始的部分但更新的排序?

这是相关的代码 .

##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>

绝对不知所措 - 任何和所有帮助都非常感谢 . 如果有任何其他细节或代码我可以提供背景,请告诉我 . 提前致谢!

1 回答

  • 1

    使用你的ejs.erb,Rails正在生成模板,但不知道你将使用它 . 然后你的Backbone应用程序通过ajax从Rails获取提示,并相应地填充模型 . 然后它是您填充和呈现模板的主干应用程序 . Rails不能在这里进行响铃,至少在这种配置中,主干需要json然后呈现模板 . 一切都发生在前端 .

    你唯一能做的就是让Rails在json里面给你帮助者的结果 . 我猜你有一个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
    

    话虽这么说,我会使用客户端解决方案,也因为:http://rails-bestpractices.com/posts/105-not-use-time_ago_in_words

相关问题