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

Dav*_*vid 10 routes ruby-on-rails ember.js ember-data

简而言之...

在构建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应用程序视图/模板一起使用?

如果我创建一个空白的projects/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应用程序布局:

<html> 
<body>   
  <section id="design-archive"></section>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

Rails路线:

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
Run Code Online (Sandbox Code Playgroud)

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')
Run Code Online (Sandbox Code Playgroud)

Rails控制器:

class ProjectsController < ApplicationController
  def index
    @projects = Project.all

    respond_to do |format|
      format.html
      format.json { render json: @projects }
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

rli*_*sey 6

您可以拥有一条引导您的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
Run Code Online (Sandbox Code Playgroud)

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

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


Dav*_*vid 4

另一个更新:我已经开始使用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
Run Code Online (Sandbox Code Playgroud)