主干:预取集合

Backbone: Pre-fetching collections

本文关键字:集合 预取 主干      更新时间:2023-09-26

我有一个主干应用程序,它在加载时需要从四个不同的集合(Rails-->JSON后端)获取数据。

这是对服务器的四次点击,我猜还有更好的方法。

我开始尝试将查询结果的Railsto_json()传递到Rails视图中的路由器初始化中,例如:

<script type="text/javascript">
  $(function() {
      window.router = new Backbonedemo.Routers.CalendarsRouter({calendars: [], tasks: <%= @tasks %>});
      Backbone.history.start();
      });
</script>

但这并没有带来快乐。

那么,在启动时运行fetch()的正确方法是什么,而不必为我想要收集的每个集合点击JSON?

查看rabl宝石。它允许您在比常规to_json更大的程度上自定义json响应。

以下是设置项目的一种基本方法,您需要在该项目中提前交付大量JSON:

首先,设置您的控制器以在页面加载时提取数据,例如localhost:3000/home会在主控制器索引中查找:

class HomeController < ApplicationController
  def index
    @user = current_user
    render 'user.json' # this line is not actually required most of the time when using backbone and proper ajax/json requests
  end
end

接下来,设置一个rabl模板,它将取代视图或部分,并向客户端返回JSON。实际上,我将使用一个partial,使加载到home/index.html视图变得简单明了:

# views/home/_user.json.rabl
object @user
attributes :id, :first_name, :last_name, :birthdate, :gender, :nickname, :email
node(:avatar_thumb_url) { |u| u.avatar.url :thumb }
node(:roles) { |u| u.roles }
node(:name) { |u| "#{u.first_name} #{u.last_name}".strip }
node(:errors) { |u| u.errors.to_hash if u.errors.present? }
child :awesome_calendars => :calendars do
  attributes :id, :date, :description
  child :events do
    attributes :title, :description
  end
end

这是一些相对花哨的rabl,它将在一个json对象中传递一堆json,包括一组相关的记录。

在加载主干的html视图中,您需要将控制器的对象传递给分部:

# views/home/index.html.erb
<script type='text/javascript'>
    $(function() {
      window.router = new Backbonedemo.Routers.CalendarsRouter(<%= render('user.json.rabl', user: @user).html_safe -%>);
    Backbone.history.start();
  });
</script>

概括一下:

  1. 控制器呈现常规html.erb视图(启动主干的视图)
  2. 该视图还呈现了一个分部——这个分部是一个严格返回JSON的rabl模板
  3. 骨干网接受JSON并对其执行任何您想要的操作

其美妙之处在于,您可以为任何控制器操作设置json.rab响应,并让它们返回各种json内容,所有这些都很容易控制。我上面做的事情是"困难"的部分,您希望在第一次页面加载时将多个表中的内容加载到一个JSON调用中——避免多个AJAX/主干提取请求。

有道理吗?我希望如此…:/如果有什么不清楚的地方,请告诉我。

我不了解Rails,但请参阅Backbone文档中的"bootstrap"示例:

<script>
  Accounts.reset(<%= @accounts.to_json %>);
  Projects.reset(<%= @projects.to_json(:collaborators => true) %>);
</script>

通常,我认为您需要创建集合对象,然后用内联JSON数据reset()它们。