3

I read the Ember Application Structure guide and now I trying to create a simple one page application with ember.js.

My home page shows a sidebar containing a list of Post objects. When I click on a list-item, on the right of the sidebar I show a read-only version of the selected item. This version has a 'Edit' button, which makes it possible to edit the item. The edit version has a 'Cancel' link to switch back to the read-only version.

I got this all working, however, when navigating back to the read-only version, the url in the address bar is not updated properly. When navigating back to my read-only version I expect the url to change from 'example.com/#posts/123/edit' to 'example.com/#posts/123', but instead I get ''example.com/#posts/undefined'.

I tried to provide a context when calling transitionTo in the 'cancel' event, but that doesn't work.

How can I navigate back to my read-only from while keeping the url pointing to the proper post (example.com/#posts/123)?

Most of my code is identical to the example in the ember guide, my router and 'edit' related code is shown below:

App.EditPostView = Em.View.extend({
  templateName: 'edit_post'
});

App.Post = DS.Model.extend({
  title: DS.attr('string'),
  body: DS.attr('string'),
  published: DS.attr('boolean')
});

App.Router = Em.Router.extend({
  enableLogging: true,
  location: 'hash',
  root: Em.Route.extend({
    index: Em.Route.extend({
      route: '/',
      redirectsTo: 'posts.index'
    })
  }),
  posts: Em.Route.extend({
  route: '/posts',  # example.com/#posts
  showPost: Em.Route.transitionTo('posts.show'),
  editPost: Em.Route.transitionTo('posts.edit'),
  index: Em.Route.extend({
    route: '/',
    connectOutlets: function(router) {
    router.get('applicationController').connectOutlet('posts', App.Post.find());
    }
  }),
  show: Em.Route.extend({
    route: '/:post_id', # example.com/#posts/123
    connectOutlets: function(router, post) {
    router.get('postsController').connectOutlet('post', post);
    }
  }),
  edit: Em.Route.extend({
    route: '/:post_id/edit', # example.com/#posts/123/edit
    connectOutlets: function(router, post) {
    router.get('postsController').connectOutlet({
      viewClass: App.EditPostView,
      controller: router.get('postController'),
      context: post
    });
    },
  }),
  cancel: function(router, event) {
    router.transitionTo('show'); # Expect this to use 'example.com/#posts/123' but instead it shows 'example.com/#posts/undefined'
  }
  })
});

# edit_post.handlebars:
  <form {{action save on="submit"}}>
  ...
  {{view Em.TextField valueBinding="title"}}
  {{view Em.TextArea valueBinding="body"}}
  ...
  <a {{action cancel}} class="btn">Cancel</a>
  </form>
sly7_7
  • 11,961
  • 3
  • 40
  • 54
bazzel
  • 833
  • 7
  • 22
  • 1
    It seems you use old action API. See this post: http://stackoverflow.com/questions/11808995/event-context-not-set-by-action-when-using-each-undefined – zaplitny Aug 04 '12 at 14:56
  • When I add a context to the action helper, I still get 'undefined': Cancel The difference with [this post](http://stackoverflow.com/questions/11808995/event-context-not-set-by-action-when-using-each-undefined) is that my action helper is not wrapped in an #each helper; my view and template are connected to a ObjectController showing a single object. – bazzel Aug 04 '12 at 19:13

1 Answers1

2

You are missing the context in transitionTo calls. You should have something like:

showPost: function (router, event) {
  var post = event.context;
  Em.Route.transitionTo('posts.show', post);
},

editPost: function (router, event) {
  var post = event.context;
  Em.Route.transitionTo('posts.edit', post);
},
Mike Aski
  • 9,180
  • 4
  • 46
  • 63
  • The following snippets still result in a valid workflow: `1: # handlebars: Cancel # App.Router: cancel: function(router, event) { router.transitionTo('show', event.contexts); } 2: # handlebars: Cancel # App.Router: cancel: function(router, event) { router.transitionTo('show'); } ` but no changes in the url show up. B.t.w. I'm using ember.js 1.0pre, manually built from github. – bazzel Aug 04 '12 at 20:05
  • Got it working: 2: `# handlebars: Cancel # App.Router: cancel: function(router, event) { post = event.context; router.transitionTo('show', post); }` Thx all – bazzel Aug 19 '12 at 15:05