Marrying angular rails

30
Marrying AngularJS with Rails [email protected] @volkertietz

Transcript of Marrying angular rails

Page 1: Marrying angular rails

Marrying AngularJS with Rails

[email protected] @volkertietz

Page 2: Marrying angular rails
Page 3: Marrying angular rails

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

outlook data - Cross-platform

Page 4: Marrying angular rails

Why Angular?

Page 5: Marrying angular rails

High initialisation time for Office.js

Page 6: Marrying angular rails

Full page reloads? :(

Page 7: Marrying angular rails

DOM interaction

Page 8: Marrying angular rails

Where you’re better off without Angular:

Page 9: Marrying angular rails

SEO

Page 10: Marrying angular rails

NoScript

Page 11: Marrying angular rails

Performance

Page 12: Marrying angular rails

Best practices

Page 13: Marrying angular rails

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

Page 14: Marrying angular rails

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 });

Page 15: Marrying angular rails

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

Page 16: Marrying angular rails

Understand the digest cycle!

Page 17: Marrying angular rails

Tools

Page 18: Marrying angular rails

Rails Integration

• Angular as a dependency

• Template handling

• DI Annotations

Page 19: Marrying angular rails

Dependencies

# Gemfile gem 'angularjs-rails'

Easiest way

//= require angular/angular

Page 20: Marrying angular rails

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

Page 21: Marrying angular rails

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

Page 22: Marrying angular rails

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

Page 23: Marrying angular rails

Templates

Option #1: Rails public folder

• Static templates

• Easy for testing (requires a running server)

• (at least) one request per template

Page 24: Marrying angular rails

Templates

Option #2: server side rendered

• Dynamic templates

• Harder to test (Rails involved)

Page 25: Marrying angular rails

Templates

Option #3: angular-rails-templates

• Static templates

• Automatically added to $templateCache => no requests

Page 26: Marrying angular rails

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

Page 27: Marrying angular rails

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

Page 28: Marrying angular rails

DI Annotations

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

# Gemfile gem ‘ngannotate-rails'

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

Page 29: Marrying angular rails

Conclusions

• AngularJS and Rails play well together

• Rails is often enough!

Page 30: Marrying angular rails

Questions?