Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ember Data Internals

9bf3a766e037b9d5a4da0a6f9d0f4f68?s=47 tomdale
December 05, 2012

Ember Data Internals

9bf3a766e037b9d5a4da0a6f9d0f4f68?s=128

tomdale

December 05, 2012
Tweet

Transcript

  1. Data

  2. • Core Concepts • Public API • Adapter/Serializer API •

    Internals
  3. Why Ember Data?

  4. Things It‘s Still Hard to Do in 2012 (which is

    bullshit)
  5. Creating two records, setting up a relationship between them, then

    saving them.
  6. Easily starting with fixture data if your server isn‘t ready

    yet.
  7. Changing the JSON representation of your model without changing app

    code.
  8. Only loading models you don‘t have cached.

  9. Keeping the DOM up-to-date with model changes.

  10. Dynamically switching between a server and offline cache.

  11. Using awesome new browser features like WebSockets and TypedArrays.

  12. These problems are SO COMMON!

  13. Why do we all do it by hand?!

  14. Convention Over Configuration

  15. conventional conventional { json: "lol" } WHY IS THIS NOT

    CONVENTIONAL?!?!
  16. Ember Data

  17. Architecture Overview

  18. Store Adapter Serializer Record Record Record Record

  19. Store Adapter Serializer Record Record Record Record Server Semantics Application

    Semantics Things that wouldn't change if your backend changed. I.e., ignoring your server protocol, how would you ideally model your data? How do you think about your models? Things that are specific to your server/backend/ persistence layer.
  20. Loading a Record

  21. Store Application App.Post.find(1) Record

  22. Store Application Person.find([1, 2, 3]) RecordArray

  23. Store Application Person.find() RecordArray

  24. // State for '/posts' App.PostsState = Ember.State.extend({ setupControllers: function() {

    var posts = App.Post.find(); this.set('controller.content', posts); } });
  25. Store Application App.Post.find(1) Adapter Record loading

  26. Store Adapter Record loading

  27. Store Record Adapter Serializer loading

  28. Store Record Adapter Serializer loaded

  29. Store Application App.Post.find(1) Record loaded

  30. Ember Data in Practice

  31. Setup

  32. App.Store = DS.Store.extend();

  33. var attr = DS.attr; App.Post = DS.Model.extend({ title: attr('string'), body:

    attr('string'), comments: DS.hasMany('App.Comment'), author: DS.belongsTo('App.User') });
  34. Finding Records

  35. var person = App.Person.find(1);

  36. person.get('isLoaded'); //=> false person.get('firstName'); //=> undefined

  37. wait a bit

  38. person.get('isLoaded'); //=> true person.get('firstName'); //=> "Tywin"

  39. Changing Records

  40. var tyrion = App.Person.find(2); tyrion.get('isDirty'); //=> false tyrion.get('firstName'); //=> "Tyrion"

    tyrion.set('firstName', "Yollo"); tyrion.get('isDirty'); //=> true
  41. store.commit(); tyrion.get('isDirty'); //=> true tyrion.get('isSaving'); //=> true

  42. wait a bit

  43. tyrion.get('isDirty'); //=> false tyrion.get('isSaving'); //=> false

  44. Creating Records

  45. var eddard = App.Person.createRecord({ firstName: "Eddard", lastName: "Stark" }); var

    robb = App.Person.createRecord({ firstName: "Robb", lastName: "Stark" });
  46. robb.set('parent', eddard); store.commit();

  47. Deleting Records

  48. tywin.deleteRecord();

  49. Transactions

  50. var transaction = store.transaction(); transaction.add(tyrion); transaction.add(tywin); transaction.commit();

  51. transaction.rollback();

  52. Record States

  53. Loaded Updated Created Deleted Clean Dirty In-Flight In-Flight Error Error

  54. var person = App.Person.find(1);

  55. person.get('isLoaded'); //=> false person.get('firstName'); //=> undefined

  56. wait a bit

  57. person.get('isLoaded'); //=> true person.get('firstName'); //=> "Tywin"

  58. isLoaded isDirty isSaving isDeleted isError isNew isValid These are derived

    from the current state object, which is awesome!
  59. • Each record has an associated state manager. • The

    store does not make changes to records directly. • Instead, events are sent to the record. • The record responds based on its current state.
  60. Uncaught Error: <DS.StateManager:ember227> could not respond to event setProperty in

    state rootState.loaded.created.inFlight. = You tried to change a record while it was being saved.
  61. // store.js record.loadedData();

  62. // model/model.js loadedData: function() { this.send('loadedData'); }

  63. // model/states.js loading: DS.State.create({ // TRANSITIONS exit: function(manager) { var

    record = get(manager, 'record'); record.trigger('didLoad'); }, // EVENTS loadedData: function(manager) { didChangeData(manager); manager.transitionTo('loaded'); } })
  64. Adapters

  65. • Are relationships saved in the parent or the child?

    • What payloads are sent to what URLs? • What actions map to what HTTP verbs? • What is the name of the primary key? • What are the names of attributes? • Are objects embedded or referred to by ID? Serializer Adapter
  66. Serializer JSONSerializer RESTSerializer

  67. Serializer Transform Values new Date() to "2007-04-05T14:30" (and vice versa)

  68. DS.JSONSerializer.registerTransform('boolean', { serialize: function(value) { return value ? 'true' :

    'false'; }, deserialize: function(value) { return value === 'false' ? false : true; } }); Serializer
  69. Serializer Add ID addId: function(data, key, id) { data[key] =

    id; }
  70. Serializer Add Attributes addAttribute: function(hash, key, value) { hash[key] =

    value; }
  71. Serializer Add Belongs-To Relationships addBelongsTo: function(hash, record, key, relationship) {

    var id = get(record, relationship.key+'.id'); if (!Ember.none(id)) { hash[key] = id; } }
  72. Serializer Extract Attributes extractAttribute: function(type, hash, attributeName) { var key

    = this._keyForAttributeName(type, attributeName); return hash[key]; }
  73. Serializer Declarative Syntax App.Adapter.map('Person', { firstName: { key: 'FIRST_NAME' }

    });
  74. Thank you. Questions? http://plus.tomdale.net http://emberjs.com @tomdale