Rails + bower + AnagularJS + CoffeeScript


現状のRails4.2 アプリ上での AngularJS + CoffeeScript のつきあいかた

使うGem

bower で依存管理

プロジェクトルートに bower.json を配置し、以下のように必要な依存定義。なお、Angular Material 利用のプロジェクトである。

{
  ..省略..
  "dependencies": {
    "jquery": "~2.1.3",
    "angular": "~1.4.0",
    "angular-cookie": "~4.0.6",
    "angular-resource": "~1.4.0",
    "angular-messages": "~1.4.0",
    "angular-animate": "~1.4.0",
    "angular-touch": "~1.4.0",
    "angular-cookies": "~1.4.0",
    "angular-material": "~0.10.0"
  }
}

んで、
設定ファイルには以下を追加しておく。

config/application.rb
config.assets.paths << config.root.join('bower_components')

application.jsapplication.css 上に必要な依存を定義

app/assets/javascripts/application.js
//= require jquery/dist/jquery.js
//= require angular/angular.js
//= require angular-animate/angular-animate.js
//= require angular-aria/angular-aria.js
//= require angular-material/angular-material.js
//= require angular-resource/angular-resource.js
//= require angular-messages/angular-messages.js
//= require angular-cookies/angular-cookies.js
//= require angular-touch/angular-touch.js
//= require angular-marked/angular-marked.js
//= require_tree ./

app/assets/stylesheets/application.scss
/*
 *= require angular/angular-csp
 *= require angular-material/angular-material
 */

とりあえずは、これで必要なコンテンツを読み込めた

これ、正直 bower-rails 使っとけばよかったかなと反省。

ngannotate-rails を使う

AngularJS上で、DI annotation を毎回書いていると辛いので、ngannotate-rails を導入しておく

gem 'ngannotate-rails'
config/application.rb
config.ng_annotate.process = true
config.ng_annotate.paths = [ 
    Rails.root.join('app', 'assets', 'javascripts').to_s
]   

コレをやることにより、DI annotation を書かなくてよくなるのでスッキリ

before
app.controller 'sampleCtrl', ['$scope', '$q', ($scope, $q) ->
]
after
app.controller 'sampleCtrl', ($scope, $q) ->

angular-rails-templates

public などに、directive などで利用するテンプレートを置いて、ロードしていると、HTTPキャッシュなどが効き厄介になることもある。そこで、angular-rails-templates を利用して、テンプレートをJavaScript化しておく。
これにより、$templateCache により、キャッシュが効いている状態にもなるので高速化も実現できる。

gem 'angular-rails-templates', '~> 0.2.0'

設定追加。

config/application.rb
# angular.js モジュール名
config.angular_templates.module_name    = 'templates'
# テンプレート名から除去するprefix
config.angular_templates.ignore_prefix  = %w(templates/)
# app/assets 以外にテンプレートを設置する場合は変更が必要
config.angular_templates.inside_paths   = [Rails.root.join('app', 'assets')]
# テンプレートは erb 形式に対応している
# erb 以外にも、str,haml,md,slim に対応。それぞれに対応したgemが追加で必要
config.angular_templates.markups        = %w(erb)
# HTMLを圧縮するか?  htmlcompressor gem が必要
config.angular_templates.htmlcompressor = false

application.js に以下を追加

app/assets/javascripts/application.js
//= require_tree ./templates

モジュールをロードする際に、template (設定ファイルで指定したもの) を指定。

app = angular.module('app', ['templates', ...])

これにより、template下に配置したHTMLファイルを、templateUrl として利用できるようになる。app/assets/javascripts/templates/foo.html を使いたい場合は以下のようになる。

app.directive 'foo', (Service) ->
  restrict: 'E'
  replace: true
  templateUrl: 'foo.html' # templates/ は ignore_prefix 設定により省略可
  link: ($scope, element, attr) ->
    # link