Ruby on rails 使用pushState Ember.js路由时,我的Rails路由应该是什么样子?
简而言之… 当构建一个Ember.js应用程序以持久化到Rails应用程序时,我应该如何处理Rails路由/视图?我想我只需要Rails来呈现application.html.erb布局,以便Ember.js应用程序初始化并处理路由/视图/模板 详细信息:Ruby on rails 使用pushState Ember.js路由时,我的Rails路由应该是什么样子?,ruby-on-rails,ember.js,routes,ember-data,Ruby On Rails,Ember.js,Routes,Ember Data,简而言之… 当构建一个Ember.js应用程序以持久化到Rails应用程序时,我应该如何处理Rails路由/视图?我想我只需要Rails来呈现application.html.erb布局,以便Ember.js应用程序初始化并处理路由/视图/模板 详细信息: <html> <body> <section id="design-archive"></section> </body> </html> @DA = Em
<html>
<body>
<section id="design-archive"></section>
</body>
</html>
@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
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')
class ProjectsController < ApplicationController
def index
@projects = Project.all
respond_to do |format|
format.html
format.json { render json: @projects }
end
end
end
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.js应用程序有机会初始化之前访问了localhost:3000,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会直接抱怨projects控制器中没有新操作。我在Rails端的projects控制器上没有“new”操作,因为我不需要它。我的Ember.js应用程序正在处理该视图/模板
最终,我只是不确定在Rails应用程序中使用Ember.js的约定是什么
谢谢你的帮助和阅读到目前为止
编辑:
<html>
<body>
<section id="design-archive"></section>
</body>
</html>
@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
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')
class ProjectsController < ApplicationController
def index
@projects = Project.all
respond_to do |format|
format.html
format.json { render json: @projects }
end
end
end
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.js路由器使用历史的能力的细节。这将使我成为非hashbang URL。这就是为什么我在处理Rails竞争路由应用程序时遇到问题的原因之一
Rails应用程序布局:
<html>
<body>
<section id="design-archive"></section>
</body>
</html>
@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
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')
class ProjectsController < ApplicationController
def index
@projects = Project.all
respond_to do |format|
format.html
format.json { render json: @projects }
end
end
end
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
铁路线路:
<html>
<body>
<section id="design-archive"></section>
</body>
</html>
@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
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')
class ProjectsController < ApplicationController
def index
@projects = Project.all
respond_to do |format|
format.html
format.json { render json: @projects }
end
end
end
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.js路由:
<html>
<body>
<section id="design-archive"></section>
</body>
</html>
@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
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')
class ProjectsController < ApplicationController
def index
@projects = Project.all
respond_to do |format|
format.html
format.json { render json: @projects }
end
end
end
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
Rails控制器:
<html>
<body>
<section id="design-archive"></section>
</body>
</html>
@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
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')
class ProjectsController < ApplicationController
def index
@projects = Project.all
respond_to do |format|
format.html
format.json { render json: @projects }
end
end
end
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
class ProjectsController
我建议您只使用一个控制器和一个操作来呈现空视图,它只是初始化您的余烬应用程序(例如,HomeController
)
然后,这就是必须管理路由的Ember路由器(所有路由都以#/
开头)
因此,所有其他Rails路由都只是一个API(由您的Ember应用程序使用),它返回一些JSON。您可以使用一个catch all路由来引导您的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
当转到完全无效的URL时,这有返回200
成功而不是404
错误的缺点,因为Rails应用程序对Ember应用程序的URL结构一无所知
如果您想避免,您可以在路由中复制您的Ember URL结构,只需将所有有效的内容指向引导路径,而不是使用catch all。我在使用特定布局响应所有HTML请求时发现。这是我目前正在使用的,似乎效果很好。唯一的限制是我不能再拥有任何非Ember.js驱动的普通HTML视图。例如,我不能在Ember之外有用户会话登录/注销表单。我想如果我到了那里,我会过那座桥的
我仍然不确定这是否是处理原始问题的最佳方法,但下面是我当前的设置。home/show.html.erb是一个空白的Rails视图
控制器:
<html>
<body>
<section id="design-archive"></section>
</body>
</html>
@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
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')
class ProjectsController < ApplicationController
def index
@projects = Project.all
respond_to do |format|
format.html
format.json { render json: @projects }
end
end
end
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
另一个更新:我已经开始为一个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
谢谢你的建议@louiscoquio。我遗漏了一点信息,那就是我正在尝试使用Ember.js的路由器功能来使用pushState历史记录。我想这可能是Rails试图路由我的应用程序时遇到问题的原因。我会更新我的帖子。谢谢@rlivsey的建议。我正在做:constraints=>{:format=>'html'}
而不是定义自定义约束对象。看见