Skip to content

Latest commit

 

History

History
202 lines (156 loc) · 5.03 KB

File metadata and controls

202 lines (156 loc) · 5.03 KB

Angular.js (+ Rails)

Use rails-assets.org to include Angular

source 'https://rubygems.org'
source 'https://rails-assets.org'

gem 'ngmin-rails' # solution to minify problem & array syntax
gem 'rails-assets-angular'
gem 'rails-assets-angular-prevent-default'
gem 'rails-assets-angular-ui-router'

Directory structure

app
  - assets
    - javascripts
      - main
        - filters
        - controllers
        - services
        - compontents # view 'E' directives(view components) 
          - header
          - dashboard
          - leaderboard
      - admin
        - filters
        - controllers
        - services
        - components
          - statistics
          - manage
      - shared
        - directives # mostly 'A' directives
        - services
        - filters
      - lib
      application.js      - only `require` sprockets directives
      init.coffee         - app initialization and configuration
      router.coffee       - ui-router routes

then in application.js

//= require angular
//= require angular-prevent-default

//= require ./init
//= require ./router
//= require_tree ./lib
//= require_tree ./main
//= require_tree ./admin
//= require_tree ./shared

View directives / components

View directives(components) should be modular by design and preferably use isolated scope(all dependencies passed explicitly through scope attrs).

You can use script similar to this one to create them easy like this:

ruby dir.rb app/assets/javascripts/main/components/dashboard/ directiveName scopeAttr1 scopAttr2

Code style

After stormy debate on weekly dev meeting we agreed to follow this code convention:

angular.module('myapp')
.service 'ServiceNameVeryLongLongName', (
  $scope, MyVeryLongServiceName,
  MyService2, MyService3
) ->

  method: (param) ->
    alert(param)

  # ...

Help ngmin handle dependencies instead of using array notation or $inject

# init.coffee
angular.module("myapp", ["ui.router"])

# controllers/main_ctrl.coffee
angular.module("myapp")
.controller "MainCtrl", (
  $scope, MyService
) ->
  # ...

Controllers

  • first params with $ prefix
  • then params passed from routing (objects)
  • last comes passed services (classes)

So instead of:

angular.module('app')
.controller 'Something', (
  $scope, Project, $http, user
) ->

it should be:

angular.module('app')
.controller 'Something', (
  $scope, $http, user, Project
) ->

Common useful settings

Inject CSRF token

# init.coffee
angular.module('myapp').config ['$httpProvider', ($httpProvider) ->
  $httpProvider.defaults.headers.common['X-CSRF-Token'] =
    angular.element(document.querySelector('meta[name=csrf-token]')).attr('content')
]

Setup template cache

# init.coffee
angular.module('myapp').config [
  '$provide', '$httpProvider', 'Rails',
  ($provide, $httpProvider, Rails) ->
    if Rails.env != 'development'
      $provide.service '$templateCache', ['$angularCacheFactory', ($angularCacheFactory) ->
        $angularCacheFactory('templateCache', {
          maxAge: 3600000 * 24 * 7,
          storageMode: 'localStorage',
          recycleFreq: 60000
        })
      ]

    $provide.factory 'railsAssetsInterceptor', ['$angularCacheFactory', ($angularCacheFactory) ->
      request: (config) ->
        if assetUrl = Rails.templates[config.url]
          config.url = assetUrl

        config
    ]

    $httpProvider.interceptors.push('railsAssetsInterceptor')
]

Use angular-translate for i18n

# rails_locales_loader
angular.module('shared').factory 'railsLocalesLoader', ['$http', ($http) ->
  (options) ->
    $http.get("locales/#{options.key}.json").then (response) ->
      response.data
    , (error) ->
      throw options.key
]

# init.coffee
angular.module('shared').config ['$translateProvider', ($translateProvider) ->
  $translateProvider.useLoader('railsLocalesLoader')
  $translateProvider.preferredLanguage('en')
]

Optimalization

  • Consider using bindonce directive to optimize number of $watches. Highly recommended in bigger, long-running projects.

IE8 dont's

Official Angular guide about IE

  • Avoid HTML5 tags and attributes (avoid HTML5 in general)

  • Avoid custom tags

    Use <div ui-view=""> or <span ui-view=""> instead of <ui-view>

  • Add id="ng-app" to the root element in conjunction with ng-app attribute

Debuging

Use batarang (stable) to debug scopes(It adds AngularJS tab in chrome developer tools). You have to enable it for particular site and enable debuger in Models section.