10

要するに...

Rails アプリに永続化する Ember.js アプリを構築する場合、Rails ルーティング/ビューをどのように処理すればよいですか? Rails で application.html.erb レイアウトをレンダリングするだけでよいので、Ember.js アプリがルーティング/ビュー/テンプレートを初期化して処理します。

詳細:

具体的には、Ember.js アプリが初期化される前にlocalhost:3000にアクセスすると、Rails はプロジェクトコントローラーで "index" アクションを実行します。インデックス テンプレートが見つからないというメッセージが表示されます。Ember.js アプリにはビュー/テンプレートがあるため、index.html.erb ビューはありません。

Rails アプリ用に空白のビューを作成する必要がありますか? ビューのレンダリングを防ぐために、Rails コントローラー アクションは何かを返す必要がありますか? または、Ember.js アプリのビュー/テンプレートと一緒に使用する通常の Rails ビューを作成する必要がありますか?

空白の projects/index.html.erb を作成してlocalhost:3000にアクセスすると、Rails がそれをレンダリングし、Ember.js が初期化してルーティングを処理します。ただし、localhost:3000/projects/newに直接アクセスすると、Rails はプロジェクト コントローラーに新しいアクションがないことを訴えます。私はそれを必要としないので、Rails 側のプロジェクトコントローラーに「新しい」アクションはありません。私の Ember.js アプリはそのビュー/テンプレートを処理しています。

最終的に、Rails アプリと一緒に Ember.js を使用するためにどのような規則が期待されるかはわかりません。

助けてくれて、ここまで読んでくれてありがとう...

編集:

Ember.js ルーターのpushState履歴を使用する機能を使用しようとしているという詳細は省略しました。これにより、ハッシュバン以外の URL が残ります。これが、Rails が競合してアプリケーションをルーティングする際に問題が発生する理由の 1 つです。

Rails アプリケーションのレイアウト:

<html> 
<body>   
  <section id="design-archive"></section>
</body>
</html>

Ember.js アプリ:

@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)

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

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
4

4 に答える 4

6

Ember アプリをブートストラップするキャッチオール ルートを持つことができます。

私のアプリの1つからの簡単な例を次に示します。

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 構造を複製し、キャッチオールを使用する代わりに、有効なものすべてをブートストラップ ルートに向けることができます。

于 2012-08-28T11:43:26.127 に答える
4

別の更新: それ以来、PushState Ember.js アプリケーションの Rails ルートを処理するために、DockYard のチュートリアル メソッドを使い始めました。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
于 2013-04-22T13:40:00.800 に答える
3

特定のレイアウトですべての 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
于 2012-08-29T12:27:35.260 に答える
0

空のビューをレンダリングするための1つのアクションを持つコントローラーを1つだけにすることをお勧めします。これは、Emberアプリケーション(HomeControllerたとえば)を初期化するだけです。

次に、これはルート(で始まるすべてのルート#/)を管理する必要があるEmberルーターです。

したがって、他のすべてのRailsルートは(Emberアプリで使用される)APIであり、JSONを返します。

于 2012-08-27T11:54:23.713 に答える