From bf6507297e46dd38ddba7c49fe8ea25ae8a5e6fc Mon Sep 17 00:00:00 2001 From: JoseĢ Mota Date: Thu, 13 Dec 2012 20:09:20 +0000 Subject: New post: Your ember is a click away from home --- ...ur-ember-app-is-a-click-away-from-home.markdown | 118 +++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 _posts/2012-12-13-your-ember-app-is-a-click-away-from-home.markdown (limited to '_posts/2012-12-13-your-ember-app-is-a-click-away-from-home.markdown') diff --git a/_posts/2012-12-13-your-ember-app-is-a-click-away-from-home.markdown b/_posts/2012-12-13-your-ember-app-is-a-click-away-from-home.markdown new file mode 100644 index 0000000..70a63e3 --- /dev/null +++ b/_posts/2012-12-13-your-ember-app-is-a-click-away-from-home.markdown @@ -0,0 +1,118 @@ +--- +layout: post +title: Your Ember app is a click away from home +tags: [ ember, development ] +published: true +--- +I've been having some time to explore Ember.js lately and I wanted to learn by +doing instead of just reading about it. So bear with me as this might probably +require some updating in the future. This is a result of trial and error and I +thought of making the Ember learning curve a little easier and share this tip. + +So I've been trying to build a simple application that manages pictures. I +started the good ol' fashioned way of manually calling all the scripts and +declaring all the templates from the index page, for argument's sake. I would +much rather have something like +[Iridium](http://github.com/radiumsoftware/iridium) to help with my development +process but I had faced some trouble with it before. + +My first step: list of pictures +------------------------------- + +The first thing that came to my mind was to have a list of pictures and allow +the user to add a new one by clicking on a link that would transition to +something like `/pictures/new`. In the pictures list template I would have +something like: + +{% highlight html %} +

Images

+{%raw%}{{#each image in controller}} +
  • {{image.title}}
  • +{{/each}} +

    + New image +

    +{%endraw%} +{% endhighlight %} + +The link in the paragraph goes to the route transition in "root". Let me give +you the router so you can better understand what I'm saying: + +{% highlight javascript %} +Exhibit.Router = Ember.Router.extend({ + root: Ember.Route.extend({ + , index: Ember.Route.extend({ + route: "/" + , connectOutlets: function(router, context) { + router.get("applicationController").connectOutlet("images", Exhibit.Image.all()); + } + , newImage: Ember.Route.transitionTo("newImage") + }) + , newImage: Ember.Route.extend({ + // ... + }) + }) +}); +{% endhighlight %} + +Inside the `index` route, the `newImage` path points to the `newImage` route +which will print a form. + +The challenge: Going back home +------------------------------ + +At this point in time, I was curious as to the possibility of aborting the +process of creating a new image and simply going back home and start over. As I +was learning, I realized that actions in the templates point to routes in the +router as a way to acknowledge an application state change. I faced the +challenge of wanting to leave the form and go back and not being able to +do it. + +I recalled that actions should be defined in the state (the route) the +application is in. Clicking on the `newImage` link transitions my app to the +`root.newImage` state. So I thought of doing something like this in the router: + +{% highlight javascript %} +Exhibit.Router = Ember.Router.extend({ + root: Ember.Route.extend({ + , index: Ember.Route.extend({ + // ... + }) + , newImage: Ember.Route.extend({ + route: "/new" + , connectOutlets: function(router, context) { + // connect the outlet + }) +===> , goHome: Ember.Route.transitionTo("root.index") + }) + }) +}); +{% endhighlight %} + +This looks rather trivial and probably won't make the point alone. What I +thought at the time when I wrote this was _should I really need to write this +transition in every single route?_ After all, going back home should be +possible for every action, every state in the app. + +The solution: Use the state machine +----------------------------------- + +After some trial and error, I ended up with this: + +{% highlight javascript %} +Exhibit.Router = Ember.Router.extend({ + root: Ember.Route.extend({ +=> goHome : Ember.Route.transitionTo("root.index") + , index : Ember.Route.extend({ /* ... */ }) + , newImage : Ember.Route.extend({ /* ... */ }) + }) +}); +{% endhighlight %} + +Since the router is a state machine, when defining the `root` route, I'm able +to add state changes there that will be inherited for every sibling state in +that tree. Both `index` and `newImage` and all the routes that are defined in +`root` will have this state change available. + +This was a finding for me as I have never grasped the concept of state machines +like this. -- cgit v1.2.3-54-g00ecf