Upload
volker-tietz
View
257
Download
1
Embed Size (px)
Citation preview
Marrying AngularJS with Rails
[email protected] @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?