Marrying angular rails

Preview:

Citation preview

Marrying AngularJS with Rails

volker.tietz@xing.com @volkertietz

- <iframe> loads page - office.js script from MS - built-in security - uses postMessage - provides access to

outlook data - Cross-platform

Why Angular?

High initialisation time for Office.js

Full page reloads? :(

DOM interaction

Where you’re better off without Angular:

SEO

NoScript

Performance

Best practices

Use promises! step1(function (value1) { step2(value1, function(value2) { step3(value2, function(value3) { step4(value3, function(value4) { // All steps successful }); }); }); });

step1() .then(function (value1) { return step2(); }) .then(function (value2) { return step3(); }) .then(function (value3) { return step4(); }) .then(function (value4) { // All steps fulfilled });

http://tinyurl.com/rughh-promises

Use services as wrappers! this.save = function () { var deferred = $q.defer(); roamingSettings().saveAsync(function (asyncResult) { if (asyncResult.status === $window.Office.AsyncResultStatus.Failed) { deferred.reject(asyncResult.error.message); } else { deferred.resolve(); } }); return deferred.promise; };

RoamingSettings.save().then(function () { // Success! }, function () { //Error });

Directivesangular.module('App') .directive('foobar', function () { return { restrict: 'E', transclude: true, require: '?^^parentDirectiveName', scope: { name: '@', data: '=', callMe: '&' }, compile: function (elm, attr, transclude) { return function link(scope, elm, attr, parentDirectiveCtrl) { } }, controller: function ($scope, Service) { } } });

https://docs.angularjs.org/guide/directive

Understand the digest cycle!

Tools

Rails Integration

• Angular as a dependency

• Template handling

• DI Annotations

Dependencies

# Gemfile gem 'angularjs-rails'

Easiest way

//= require angular/angular

DependenciesManage dependencies with bower

# config/initializers/assets.rb Rails.application.config.assets.paths << Rails.root.join('vendor', 'assets', 'components')

// .bowerrc { "directory": "vendor/assets/components" }

$ bower install angularjs

Dependencies

# config/initializers/assets.rb Rails.application.config.assets.precompile += %w( office365.js office365.css angular.js )

Dedicated manifest files

// app/assets/javascripts/office365.js //= require office365/modules.js //= require office365/routes.js //= require office365/config.js //= require office365/app.js //= require_tree ./office365/app //= require_tree ./office365/locales

Dependencies

Dedicated manifest files // app/assets/javascripts/angular.js //= require angular/angular //= require angular-route/angular-route //= require angular-translate/angular-translate //= require angular-animate/angular-animate

Templates

Option #1: Rails public folder

• Static templates

• Easy for testing (requires a running server)

• (at least) one request per template

Templates

Option #2: server side rendered

• Dynamic templates

• Harder to test (Rails involved)

Templates

Option #3: angular-rails-templates

• Static templates

• Automatically added to $templateCache => no requests

Templates # Gemfile gem ‘angular-rails-templates'

Add the gem

# apps/assets/javascripts/office365.js //= require angular-rails-templates //= require_tree ./office365/templates

Include it in the asset pipeline

# apps/assets/javascripts/office365/modules.js angular.module('XNG-Office365-App', ['templates']);

Add it as dependency in your Angular module

Testing Templates

$ npm install karma-ng-html2js-preprocessorKarma ng-html2js-preprocessor

// karma.conf.js

processors: { 'app/assets/javascripts/office365/templates/*.html': 'ng-html2js' }, ngHtml2JsPreprocessor: { // strip this from the file path stripPrefix: 'app/assets/javascripts/', // module name moduleName: 'templates' }

Add it to the karma config

DI Annotations

angular.module('App') .controller('ContactsCtrl', function ($scope) { });

# Gemfile gem ‘ngannotate-rails'

angular.module('App') .controller('ContactsCtrl', ['$scope', function ($scope) { }]);

Conclusions

• AngularJS and Rails play well together

• Rails is often enough!

Questions?