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

A Discourse with Ember.js

A Discourse with Ember.js

Discourse is one of the most starred projects on Github, and in its first year was featured in their state of the octoverse as one of the open source projects with the highest momentum.

When Discourse was released, about a year ago, I didn't know either Ember.js or Ruby on Rails. In this talk, I will share my experience and challenges learning Ember.js while contributing to one of the largest open-source Ember.js project and present the things that worked well and the ones that didn't.

Régis Hanol

August 28, 2014
Tweet

More Decks by Régis Hanol

Other Decks in Programming

Transcript

  1. Ember.js incorporates common idioms so you can focus on what

    makes your app special, not reinventing the wheel.
  2. Ember.Application.create({ LOG_TRANSITIONS_INTERNAL: true }); Attempting URL transition to / Transition

    #0: application: calling beforeModel hook Transition #0: application: calling deserialize hook Transition #0: application: calling afterModel hook Transition #0: discovery: calling beforeModel hook Transition #0: discovery: calling deserialize hook Transition #0: discovery: calling afterModel hook Transition #0: discovery.latest: calling beforeModel hook Transition #0: discovery.latest: calling deserialize hook Transition #0: discovery.latest: calling afterModel hook Transition #0: Resolved all models on destination route; finalizing transition. Transition #0: TRANSITION COMPLETE.
  3. Ember.Application.create({ LOG_VIEW_LOOKUPS: true }); Rendering application with <Discourse.ApplicationView:ember1278> Object {fullName:

    "view:application"} ! Rendering topic with <Discourse.TopicView:ember1330> Object {fullName: "view:topic"} ! Could not find "topic.fromParams" template or view. Nothing will be rendered Object {fullName: "template:topic.fromParams"} ! Rendering discovery with default view <Ember._MetamorphView:ember1981> Object {fullName: "view:discovery"}
  4. Ember.Application.create({ LOG_ACTIVE_GENERATION: true }); generated -> route:adminUsers Object {fullName: "route:adminUsers"}

    generated -> route:adminGroups.index Object {fullName: "route:adminGroups.index"} generated -> route:adminEmail Object {fullName: "route:adminEmail"} generated -> route:adminFlags Object {fullName: "route:adminFlags"} generated -> route:adminLogs Object {fullName: "route:adminLogs"} generated -> route:adminCustomize Object {fullName: "route:adminCustomize"}
  5. Ember.Application.create({ LOG_RESOLVER: true }); [✓] view:modal ............................. Discourse.ModalView [✓] controller:modal

    ....................... Discourse.ModalController [ ] template:modal ......................... template at modal [✓] template:modal/modal ................... template at modal/modal [✓] view:topic-entrance .................... Discourse.TopicEntranceView [✓] controller:topic-entrance .............. Discourse.TopicEntranceController [✓] template:topic-entrance ................ template at topic-entrance [✓] controller:composer .................... Discourse.ComposerController [✓] controller:composer-messages ........... Discourse.ComposerMessagesController [✓] template:composer ...................... template at composer [✓] view:composer-messages ................. Discourse.ComposerMessagesView [ ] template:composer-messages ............. template at composer-messages
  6. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Ember Tests</title> <link rel="stylesheet"

    href="qunit.css"> </head> <body> <div id="qunit"></div> <div id="qunit-fixture"></div> <div id="ember-testing"></div> <script src="qunit.js"></script> <script src="ember_code.js"></script> <script src="test_code.js"></script> </body> </html>
  7. test(“creating a post", function(){ ! // 1 - visit visit(“/posts/new");

    ! // 2 - interact fillIn("input.title", "My new post"); click(“button.submit"); ! ! ! ! ! ! ! });
  8. test(“creating a post", function(){ ! // 1 - visit visit(“/posts/new");

    ! // 2 - interact fillIn("input.title", "My new post"); click(“button.submit"); ! ! ! // 3 - check equal(find(“ul.posts li:last").text(), "My new post”); ! ! });
  9. test(“creating a post", function(){ ! // 1 - visit visit(“/posts/new");

    ! // 2 - interact fillIn("input.title", "My new post"); click(“button.submit"); ! ! ! // 3 - check equal(find(“ul.posts li:last").text(), "My new post”); ! ! });
  10. test(“creating a post", function(){ ! // 1 - visit visit(“/posts/new");

    ! // 2 - interact fillIn("input.title", "My new post"); click(“button.submit"); ! // wait for asynchronous helpers above to complete andThen(function(){ // 3 - check equal(find(“ul.posts li:last").text(), "My new post”); }); ! });
  11. App.Post = Ember.Object.extend({ status: 'draft', ! isPublished: function() { return

    this.get(‘status’) == 'published'; }.property(‘status') ! });
  12. App.Post = Ember.Object.extend({ status: 'draft', ! isPublished: function() { return

    this.get(‘status’) == 'published'; }.property(‘status') ! }); test(‘isPublished is false by default', function() { ! ! ! });
  13. App.Post = Ember.Object.extend({ status: 'draft', ! isPublished: function() { return

    this.get(‘status’) == 'published'; }.property(‘status') ! }); test(‘isPublished is false by default', function() { var post = App.Post.create(); ! ! });
  14. App.Post = Ember.Object.extend({ status: 'draft', ! isPublished: function() { return

    this.get(‘status’) == 'published'; }.property(‘status') ! }); test(‘isPublished is false by default', function() { var post = App.Post.create(); ! equal(post.get(‘isPublished’), false); });
  15. test(‘isPublished is true when published', function() { ! ! !

    }); App.Post = Ember.Object.extend({ status: 'draft', ! isPublished: function() { return this.get(‘status’) == 'published'; }.property(‘status') ! });
  16. test(‘isPublished is true when published', function() { var post =

    App.Post.create(); ! ! }); App.Post = Ember.Object.extend({ status: 'draft', ! isPublished: function() { return this.get(‘status’) == 'published'; }.property(‘status') ! });
  17. test(‘isPublished is true when published', function() { var post =

    App.Post.create(); post.set('status', ‘published'); ! }); App.Post = Ember.Object.extend({ status: 'draft', ! isPublished: function() { return this.get(‘status’) == 'published'; }.property(‘status') ! });
  18. test(‘isPublished is true when published', function() { var post =

    App.Post.create(); post.set('status', 'published'); equal(post.get(‘isPublished’), true); }); App.Post = Ember.Object.extend({ status: 'draft', ! isPublished: function() { return this.get(‘status’) == 'published'; }.property(‘status') ! });