Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
Rich Object Models &
Angular
Ben Teese, Shine Technologies
Overview
Why?
Loading Data
Adding Business Logic
Advanced Stuff
Most of the apps I build are

CRUD
...it was nice
WARNING
The remainder of this presentation
contains UX that some viewers may find
disturbing
Proposal
Internal
Currency
NonRecurring
Engineering

External
Currency

Customer

Shipsets

External
Cost Items

Material
...
Restangular
Getting Stuff
// GET /proposals
Restangular.all('proposals').getList().then(
function(proposals) {
$scope.proposals = prop...
or...
// GET /proposals
$scope.proposals =
Restangular.all('proposals').getList().
$object;
Getting Nested Stuff
// GET /proposals/:id/cost_items
$scope.proposal.getList('cost_items').then(
function(costItems) {
$s...
Rich Models
angular.module('pimpMyPlane.services', ['restangular']).
factory('ProposalSvc', function(Restangular) {
Restangular.extend...
A Model Mixin
angular.module('pimpMyPlane.models').
factory('Proposal', function() {
return {
profit: function() {
return ...
Using the Mixin
angular.module('pimpMyPlane.services',
['restangular', 'pimpMyPlane.models']
).factory('ProposalSvc', func...
What about nested models?
angular.module('pimpMyPlane.services', ['restangular']).
factory('ProposalSvc', function(Restang...
Introduce mixInto()
angular.module('pimpMyPlane.services',
['restangular', 'pimpMyPlane.models']
).
factory('Proposals', f...
angular.module('pimpMyPlane.models').
factory('Proposal', function(
Currency, RecurringEngineering, NonRecurringEngineerin...
Proposal
Internal
Currency
NonRecurring
Engineering

External
Currency

Customer

Recurring
Engineering

Shipsets

Externa...
Shazam
Identity Maps
Proposal
Internal
Currency
NonRecurring
Engineering

External
Currency

Customer

Recurring
Engineering

Shipsets

Externa...
Identity Map
“currency”:1

EUR

“currency”:2
...

USD
...

“department”:1

Finance

“department”:2

IT

...

...
Mapping Nested Currencies
angular.module('pimpMyPlane.models').
factory('Money', function(Currency, identityMap) {
return ...
Mapping RESTful Currencies
angular.module('pimpMyPlane.services',
['restangular', 'pimpMyPlane.models']
).factory('Currenc...
Getter Functions
(Uniform Access Principle)
angular.module('pimpMyPlane.models').
factory('Proposal', function(extendWithGetters) {
return {
mixInto: function(obj) {
...
Memoization
angular.module('pimpMyPlane.models').
factory('Proposal', function(Model) {
return Model.extend({
memoize: ['revenue', 'co...
Unmemoization
<div ng-controller="ProposalCtrl">
...
<input type="number"
ng-model="currency.conversionFactor"
ng-change="...
Computed Properties
angular.module('pimpMyPlane.models').
factory('Proposal', function(...) {
return Model.extend({
...
computedProperties: {
...
...needs more work
Let’s Wrap This Up
Shrink-wrapped
Boeing 737
Rich Models can work
Identity Maps
Getters, Memoization
Computed properties
Please enjoy the remainder of your flight

@benteese
Rich Object Models & Angular.js
Rich Object Models & Angular.js
Rich Object Models & Angular.js
Rich Object Models & Angular.js
Prochain SlideShare
Chargement dans…5
×

Rich Object Models & Angular.js

9 736 vues

Publié le

Super excited about Angular? Ready to change the world and build a super-heroic app? With directives, Angular has pretty much nailed it when it comes to interacting with the DOM. And plain-old Javascript objects as models? AWESOME!

Wait, hang on. Say that you're building a app that has lots of business logic and interrelated data. For that sort of app, history shows us that a rich object model can often be the best place to put your logic and data relationships - from both a testing and ease-of-development perspective. That's the approach that frameworks like Ember advocate - but Ember forces you to extend on its own object model.

In this talk I'll ask whether we can get the best of both worlds - a rich data model, whilst still using plain-old Javascript objects. We'll delve into things like:

- Lazy-loading data relationships between models
- Decorating loaded data with business logic
- Object identity uniqueness (critical for bindings to work as expected)
- Computed properties for models

Attendees will leave with an understanding of how a rich object model can help them build beautiful, fast and easy-to-maintain apps.

Publié dans : Technologie, Économie & finance
  • ⇒⇒⇒WRITE-MY-PAPER.net ⇐⇐⇐ I love this site. It always finds me the best tutors in accordance with my needs. I have been using it since last year. The prices are not expensive compared to other sites. I am glad I discored this site:)
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • Follow the link, new dating source: ♥♥♥ http://bit.ly/2Qu6Caa ♥♥♥
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • Sex in your area is here: ♥♥♥ http://bit.ly/2Qu6Caa ♥♥♥
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • I'm debating if Restangular is a good fit when all of the requests are just gets. And regarding rich object model, do you have an example of a model class that I can download/view? Do your model classes only consist of getters/setters or you add behavior to them too?
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici
  • Link to youtube presentation: http://www.youtube.com/watch?v=JfykD-0tpjI
       Répondre 
    Voulez-vous vraiment ?  Oui  Non
    Votre message apparaîtra ici

Rich Object Models & Angular.js

  1. 1. Rich Object Models & Angular Ben Teese, Shine Technologies
  2. 2. Overview Why? Loading Data Adding Business Logic Advanced Stuff
  3. 3. Most of the apps I build are CRUD
  4. 4. ...it was nice
  5. 5. WARNING The remainder of this presentation contains UX that some viewers may find disturbing
  6. 6. Proposal Internal Currency NonRecurring Engineering External Currency Customer Shipsets External Cost Items Material Cost Items Internal Cost Items Customer Type Cost Cost Department Sales Price Override Currency Currency OMG Recurring Engineering Details Years Line Replaceable Unit Currency Customer Type Prices External Cost Items Internal Cost Item Subassemblies Standard Sales Price Spare Parts Sales Price Customer Type Cost Department Supplier Purchase Price Ranges Currency Sales Price Currency Currency Currency Purchase Price Currency
  7. 7. Restangular
  8. 8. Getting Stuff // GET /proposals Restangular.all('proposals').getList().then( function(proposals) { $scope.proposals = proposals; } );
  9. 9. or... // GET /proposals $scope.proposals = Restangular.all('proposals').getList(). $object;
  10. 10. Getting Nested Stuff // GET /proposals/:id/cost_items $scope.proposal.getList('cost_items').then( function(costItems) { $scope.costItems = costItems; } );
  11. 11. Rich Models
  12. 12. angular.module('pimpMyPlane.services', ['restangular']). factory('ProposalSvc', function(Restangular) { Restangular.extendModel('proposals', function(obj) { return angular.extend(obj, {! profit: function() { return this.revenue().minus(this.cost()); }, revenue: function() { return this.price(). convertTo(this.internalCurrency); } ... }); }); return Restangular.all('proposals'); })
  13. 13. A Model Mixin angular.module('pimpMyPlane.models'). factory('Proposal', function() { return { profit: function() { return this.revenue().minus(this.cost()); }, revenue: function() { return this.price(). convertTo(this.internalCurrency); }, ... }; }
  14. 14. Using the Mixin angular.module('pimpMyPlane.services', ['restangular', 'pimpMyPlane.models'] ).factory('ProposalSvc', function(Restangular, Proposal){ Restangular.extendModel('proposals', function(obj) { return angular.extend(obj, Proposal); }); return Restangular.all('proposals'); });
  15. 15. What about nested models? angular.module('pimpMyPlane.services', ['restangular']). factory('ProposalSvc', function(Restangular) { Restangular.extendModel('proposals', function(obj) { angular.extend(obj.recurringEngineering, { ... }); angular.extend(obj.nonRecurringEngineering, { ... }); angular.extend(obj.internalCurrency, { ... }); angular.extend(obj.externalCurrency, { ... }); return angular.extend(obj, Proposal); }); ... })
  16. 16. Introduce mixInto() angular.module('pimpMyPlane.services', ['restangular', 'pimpMyPlane.models'] ). factory('Proposals', function(Restangular, Proposal) { Restangular.extendModel('proposals', function(obj) { return Proposal.mixInto(obj); }); ... });
  17. 17. angular.module('pimpMyPlane.models'). factory('Proposal', function( Currency, RecurringEngineering, NonRecurringEngineering ) { return { mixInto: function(obj) { RecurringEngineering.mixInto( obj.recurringEngineering ); NonRecurringEngineering.mixInto( obj.nonRecurringEngineering ); Currency.mixInto(obj.internalCurrency); Currency.mixInto(obj.externalCurrency)) return angular.extend(obj, this); }, profit: function() { return this.revenue().minus(this.cost()); }, ... }; });
  18. 18. Proposal Internal Currency NonRecurring Engineering External Currency Customer Recurring Engineering Shipsets External Cost Items Material Cost Items Internal Cost Items Customer Type Cost Cost Department Sales Price Override Currency Currency Details Years Line Replaceable Unit Currency Customer Type Prices External Cost Items Internal Cost Item Subassemblies Standard Sales Price Spare Parts Sales Price Customer Type Cost Department Supplier Purchase Price Ranges Currency Sales Price Currency Currency Currency Purchase Price Currency
  19. 19. Shazam
  20. 20. Identity Maps
  21. 21. Proposal Internal Currency NonRecurring Engineering External Currency Customer Recurring Engineering Shipsets External Cost Items Material Cost Items Internal Cost Items Customer Type Cost Cost Department Sales Price Override Currency Currency Details Years Line Replaceable Unit Currency Customer Type Prices External Cost Items Internal Cost Item Subassemblies Standard Sales Price Spare Parts Sales Price Customer Type Cost Department Supplier Purchase Price Ranges Currency Sales Price Currency Currency Currency Purchase Price Currency
  22. 22. Identity Map “currency”:1 EUR “currency”:2 ... USD ... “department”:1 Finance “department”:2 IT ... ...
  23. 23. Mapping Nested Currencies angular.module('pimpMyPlane.models'). factory('Money', function(Currency, identityMap) { return { mixInto: function(obj) { obj.currency = identityMap( 'currency', Currency.mixInto(obj.currency) ); angular.extend(object, this); }, ... });
  24. 24. Mapping RESTful Currencies angular.module('pimpMyPlane.services', ['restangular', 'pimpMyPlane.models'] ).factory('CurrenciesSvc', function( Restangular, Currency, identityMap ) { Restangular.extendModel('currencies', function(obj){ return identityMap( 'currency', Currency.mixInto(obj) ); }); return Restangular.all('currencies'); });
  25. 25. Getter Functions (Uniform Access Principle)
  26. 26. angular.module('pimpMyPlane.models'). factory('Proposal', function(extendWithGetters) { return { mixInto: function(obj) { ... return extendWithGetters(obj, this); }, get profit() { return this.revenue.minus(this.cost); }, get revenue() { return this.price.convertTo( this.internalCurrency ); }, ... }; } );
  27. 27. Memoization
  28. 28. angular.module('pimpMyPlane.models'). factory('Proposal', function(Model) { return Model.extend({ memoize: ['revenue', 'cost'], ... get profit() { return this.revenue.minus(this.cost); }, get revenue() { return this.price.convertTo( this.internalCurrency ); }, ... }; } );
  29. 29. Unmemoization <div ng-controller="ProposalCtrl"> ... <input type="number" ng-model="currency.conversionFactor" ng-change="proposal.unmemoize()"></input> ... <table> <tr> <td>Number of Aircraft</td> <td> <input type="number" min="1" ng-model="proposal.numberOfAircraft" ng-change="proposal.unmemoize()"></input> </td> </tr> </table> </div>
  30. 30. Computed Properties
  31. 31. angular.module('pimpMyPlane.models'). factory('Proposal', function(...) { return Model.extend({ ... computedProperties: { profit: [function() { return this.revenue.minus(this.cost); }, 'revenue', 'cost'], cost: [function() { return this.recurringEngineering.cost.plus( this.nonRecurringEngineering.cost ); }, 'recurringEngineering.cost', 'nonRecurringEngineering.cost'] }, }); });
  32. 32. ...needs more work
  33. 33. Let’s Wrap This Up Shrink-wrapped Boeing 737 Rich Models can work Identity Maps Getters, Memoization Computed properties
  34. 34. Please enjoy the remainder of your flight @benteese

×