angularjs on rails by daniele spinosa
DESCRIPTION
Come integrare AngularJS in un'applicazione Rails.TRANSCRIPT
AngularJS on RailsCome integrare AngularJS in un'applicazione Rails senza essere insultati dagli altri sviluppatori.
Quando programmi,non c'è differenza tra te
e un cinghiale!1
Sconosciuto Toscano
Creare una API json in RoR per dialogare con AngularJS
AngularJS: API racchiusa in un Servicedefinire una 'resource' intorno alla rotta della API
LegoSet = $resource("/api/v1/lego_sets/:id", {id: "@id"}, ...)
API + versioning# routes.rb
namespace :api, defaults: {format: 'json'} do namespace :v1 do resources :lego_sets, only: [:index, :show] do resources :lego_parts, only: [:show] end endend
GET http://lego_app.com/api/v1/lego_sets/GET http://lego_app.com/api/v1/lego_sets/21103GET http://lego_app.com/api/v1/lego_parts/3001
app `--controllers |-- api | `-- v1 | |-- lego_sets_controller.rb | `-- lego_parts_controller.rb |-- application_controller.rb
/app/controllers/api/v1/lego_sets_controller.rbmodule Api::V1 class LegoSetsController < ApplicationController respond_to :json
def index respond_with LegoSet.all end
def show respond_with LegoSet.find(params[:id]) end endend
Rails 4 request paramsProtezione dal mass-assignment spostata nel controller.Utile creare un helper method
def safe_lego_set_params def safe_params params.require(:lego_set).permit(:set_id, :piece_id, :num, ...) endend
Si puo agire direttamente nel Layoutapp/views/layouts/application.html.erb
...<head> <%= javascript_include_tag "//ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js" %> <%= javascript_include_tag "//ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-resource.min.js" %></head>
Rapido ma molto da cinghiale...
Si può usare l'asset pipelineI files di angular possono essere inseriti manualmente in
app/assets/javascripts/application.js
//= require jquery//= require jquery_ujs...//= require lib/angular.min//= require lib/angular.resource//= require <nome_app_angular>...
La soluzione per tutte le stagionigem angularjs-railsbundle
quindi
//= require angular
oppure, se si vuole usare la versione instabile
//= require unstable/angular
Indipendentemente dalla soluzione adottata è
necessario prendere alcune precauzioni per evitare grattacapi in produzione.
Proteggere il codice Angular (1)1. Mangle: false
disabilitare il renaming delle variabili (mangle)
# nel file config/environments/production.rbconfig.assets.js_compressor = Uglifier.new(mangle: false)
Proteggere il codice Angular (2)2. depenency injection naming
Specificare i nomi degli argomenti in ogni funzione che accetta 'services' ad es.:@LegoCtrl = ("$scope", "LegoSet", $scope, LegoSet) ->
angular.module('LegoApp').factory 'LegoSet', [ $resource, ($resource) -> ...] ^ ^
Proteggere il codice Angular (3)3. usare una gemma
gem 'ngannotate-rails'
https://github.com/kikonen/ngannotate-rails
Strutturare il codice JS (1)require risorse angular dopo i turbolinks e prima di tree// app/assets/javascript/application.js
//= require jquery//= require jquery_ujs//= require turbolinks
//= require lib/angular.min//= require lib/angular.resource//= require <nome_app_angular>
//= require tree
Strutturare il codice JS (2)Ogni app. AngularJS consiste in un modulo principale, controllers, directives e services. Suddividere il codice in cartelle all'interno di app/assets/javascripts:
4 controllers
4 directives
4 services
...E lib per le tutte le altre dipendenze
Sfruttare la protezione CSRF di RoRProteggere l'applicazinone da attacchi cross-site request forgery attraverso un token inserito nella sezione head di ogni pagina. Usare quel token in tutte le API requests.
application.js.coffee
LegoApp.config ($httpProvider) -> authToken = $("meta[name=\"csrf-token\"]").attr("content") $httpProvider.defaults.headers.common["X-CSRF-TOKEN"] = authToken
Usare i turbolinksNon usate il tag ng-app nell'html. Usate page:loadapplication.js.coffee$(document).on 'page:load', -> $('[ng-app]').each -> module = $(this).attr('ng-app') angular.bootstrap(this, [module])
In questo modo l'applicazione AngularJS verrà inizializzata correttamente ogni volta che i turbolinks fanno fetch&replace.
Ulteriori alternative
Yeoman4 SPA (single page applications)
4 sviluppatori specializzati in JS
1. rails new lego_app && cd lego_app2. mkdir angular && cd angular3. npm install -g yo grunt-cli bower4. npm install generator-angular generator-karma5. yo angular6. npm install && bower install
Bower + Grunt(rails senza asset pipeline)
4 molto disaccoppiato
4 perfetto se si prevede un upgrade di Rails
rails-assets
Proxy tra Bundler e Bower: converte i componenti Bower in rails gems.
1. aggiungere https://rails-assets.org come gem source
2. indicare i componenti Bower da convertire: gem 'rails-assets-BOWER_PACKAGE_NAME'
3. bundle install: recupera il componente dal registro di Bower e lo 'impacchetta' come gem
Non usare Rails4 rails-api
4 Sinatra
4 AngularFire + Firebase
4 NodeJS
4 Go
Sviluppate per bene.
grazie.@microspino