我的Rails路由应该与pushState Ember.js路由一起使用?

简而言之…

在构建Ember.js应用程序以持久化到Rails应用程序时,我应该如何处理Rails路由/视图? 我认为我只需要Rails来呈现application.html.erb布局,以便Ember.js应用程序初始化并处理路由/视图/模板。

细节:

具体来说,如果我访问localhost:3000 ,在我的Ember.js应用程序有机会初始化之前,Rails会在项目控制器上执行“索引”操作。 它会抱怨缺少索引模板。 我没有index.html.erb视图,因为我的Ember.js应用程序有一个视图/模板。

我应该为Rails应用程序创建空白视图吗? 我的Rails控制器操作应该返回一些东西以防止它呈现视图吗? 或者我希望构建正常的Rails视图以与Ember.js应用程序视图/模板一起使用?

如果我创建一个空白项目/ index.html.erb并访问localhost:3000 ,Rails将呈现它,Ember.js将从那时开始初始化并处理路由。 但是,如果我直接访问localhost:3000 / projects / new ,Rails会抱怨项目控制器中没有新操作。 我在Rails端的项目控制器上没有“新”操作,因为我不需要它。 我的Ember.js应用正在处理该视图/模板。

最后,我只是不确定在Rails应用程序旁边使用Ember.js的约定。

感谢您的帮助,并阅读此…

编辑:

我遗漏了我试图使用Ember.js路由器使用pushState历史记录的能力的细节。 这将留下非hashbang URL。 这就是为什么我在处理Rails竞争路由我的应用程序时遇到问题的原因之一。

Rails应用程序布局:

  

Ember.js App:

 @DA = Em.Application.create name: 'Design Archive' VERSION: '0.1' rootElement: '#design-archive' ApplicationController: Em.Controller.extend() ApplicationView: Em.View.extend templateName: 'application' DA.initialize(DA.Router) 

导轨路线:

 DesignArchive::Application.routes.draw do resources :clients, :only => [:new, :create, :index, :show, :destroy] resources :projects, :only => [:new, :create, :index, :show, :destroy] root :to => 'projects#index' end 

Ember.js路线:

 DA.Router = Em.Router.create location: 'history' root: Em.Route.extend index: Em.Route.extend route: '/' redirectsTo: 'projects' # Actions doProjects: (router) -> router.transitionTo('projects') doProjectsNew: (router) -> router.transitionTo('newProject') # Routes projects: Em.Route.extend route: '/projects' index: Em.Route.extend router: '/' connectOutlets: (router) -> router.get('applicationController').connectOutlet('projects', DA.Project.find()) showProject: Em.Route.transitionTo('project') project: Em.Route.extend route: '/projects/:project_id' connectOutlets: (router, project) -> router.get('applicationController').connectOutlet('project', project) projectsIndex: Em.Route.transitionTo('projects') newProject: Em.Route.extend route: '/projects/new' connectOutlets: (router) -> router.get('applicationController').connectOutlet('projectsNew') 

Rails控制器:

 class ProjectsController < ApplicationController def index @projects = Project.all respond_to do |format| format.html format.json { render json: @projects } end end end 

您可以拥有一条引导您的Ember应用程序的全能路线。

以下是我的一个应用程序的简化示例:

 App::Application.routes.draw do match "/login" => "sessions#new", :via => :get, :as => :login match "/login" => "sessions#create", :via => :post match "/logout" => "sessions#destroy", :via => :post, :as => :logout match "/attachments/:id" => "attachments#download" match "/avatars/:id" => "avatars#show" root :to => 'pages#bootstrap' # anything not matched by the above should be served the bootstrap match "/*path" => "pages#bootstrap" end 

由于Rails应用程序对Ember应用程序的URL结构一无所知,因此在完全无效的URL时返回200成功而不是404错误的缺点。

如果你想避免这种情况,你可以在路由中复制你的Ember URL结构,只需将所有有效的内容指向引导路由,而不是使用catch-all。

另一个更新:我已经开始使用DockYard的教程方法来处理pushState Ember.js应用程序的Rails路由。 这是一个Rails routes.rb示例:

 EmberApp::Application.routes.draw do class FormatTest attr_accessor :mime_type def initialize(format) @mime_type = Mime::Type.lookup_by_extension(format) end def matches?(request) request.format == mime_type end end get '*foo', :to => 'ember#index', :constraints => FormatTest.new(:html) get '/', :to => 'ember#index', :constraints => FormatTest.new(:html) end 

我发现这篇文章回应了具有特定布局的所有HTML请求。 这是我目前正在使用的,似乎运作良好。 唯一的限制是我不能再使用任何非Ember.js驱动的普通HTML视图。 例如,我无法在Ember之外拥有user_session登录/注销表单。 如果我到达那里,我想我会越过那座桥。

我仍然不确定这是否是解决原始问题的最佳方法,但下面是我目前的设置。 home / show.html.erb是一个空白的Rails视图。

控制器:

 class ApplicationController < ActionController::Base protect_from_forgery before_filter :render_default_view private def render_default_view return if request.xhr? respond_to do |format| format.html { render 'home/show' } end end end class HomeController < ApplicationController def show end end class ProjectsController < ApplicationController def new end def index end def show end end 

路线:

 DesignArchive::Application.routes.draw do resources :projects, :only => [:new, :index, :show] namespace :api do resources :projects, :only => [:create, :index, :show, :destroy] end root :to => 'home#show' end 

我建议您只有一个控制器,其中一个操作用于渲染空视图,这只是初始化您的Ember应用程序(例如HomeController )。

然后,这是必须管理路由的Ember路由器(所有以#/开头的路由)。

因此,所有其他Rails路由只是一个API(由您的Ember应用程序使用),它返回一些JSON。