ember.js - Ember, Ember-data, and jquery-ui.dialog, "Oh my!" -
the task:
open form in lightbox create new "event"; opened form should bookmarkable.
the road blocks:
- there examples of opening lightbox using
{{action}}
tags, not find 1 opened in own route. - there many examples using older versions of ember.js.
- there not lot of documentation related ember-data , rest (i know, know...it isn't "production ready").
the problem:
the fields in form not being tied backing model "null" being posted servlet (a spring controller).
my first iteration not far off final outcome (jsfiddle). thing made works swapping this:
ep.eventsnewroute = ember.route.extend({ ... setupcontroller : function(controller, model) { controller.set("model", model); }, ... });
...for this:
ep.eventsnewroute = ember.route.extend({ ... setupcontroller : function(controller, model) { this.controllerfor("events-new").set("model", model); }, ... });
the question:
why setupcontroller function need call controllerfor
in order set model?
and finally, since struggled find fully-functional example, wanted make accessible (and discover improvements).
here's fiddle: http://jsfiddle.net/6thj4/1/
here few snippets.
html:
<script type="text/x-handlebars"> <div> <ul> {{#linkto "events.new" tagname="li"}} add event {{/linkto}} </ul> </div> {{outlet events-new}} </script> <script type="text/x-handlebars" data-template-name="events-new"> <form> <div> <label>event name:</label> {{view ember.textfield valuebinding="name"}} </div> <div> <label>host name:</label> {{view ember.textfield valuebinding="hostname"}} </div> </form> </script>
javascript:
... ep.router.map(function() { this.resource("events", function() { this.route("new"); }); }); ep.eventsnewroute = ember.route.extend({ model : function() { return ep.event.createrecord(); }, setupcontroller : function(controller, model) { //controller.set("model", model); // doesn't work? why not? this.controllerfor("events-new").set("model", model); // differently? }, ... }); ep.eventsnewcontroller = ember.objectcontroller.extend({ save : function() { this.get("content.transaction").commit(); // "content.store" commit _everything modified_, have 1 element changed, "content.transaction" necessary. } }); ep.eventsnewview = ember.view.extend({ ... }); ep.event = ds.model.extend({ name : ds.attr("string"), hostname : ds.attr("string") });
resources:
- http://emberjs.com/guides/routing/setting-up-a-controller/
- http://emberjs.com/guides/getting-started/toggle-all-todos/ (trying mimic learned, morph add-new new route)
- writing lightboxview causes problems / integrating dom manipulating jquery-plugins makes actions unusable (lightbox "example")
- dependable views in ember (another lightbox "example" doesn't have routes lightbox opening)
why setupcontroller function need call controllerfor in order set model?
ember makes urls integral part of conventions. means state
of application represented route on. you've grokked of correctly. there couple of subtle nuances, clarify below.
first consider app following urls,
- /posts - shows list of blog posts.
- /posts/1 - shows single blog post.
and clicking on post in list @ /posts
takes /posts/1
.
given scenario, there 2 ways user see post @ /posts/1
.
- by going
/posts
, clicking on 1st post. - by typing in
/posts/1
, via bookmarks etc.
in both these cases, postroute
/posts/1
need model corresponding post
id 1.
consider direct typing scenario first. provide way lookup id=1 post model, use,
model: function(params) { return app.post.find(params.post_id); }
your template post model , can render using it's properties.
now consider second scenario. clicking on post id=1 takes /posts/1
. template use linkto
this.
{{#linkto 'post' post}} {{post.title}} {{/linkto}}
here passing in post
model linkto
helper. serializes data post url, ie:- '/posts/1'. when click on link ember realizes needs render postroute
has post model. skips model hook , directly calls setupcontroller
.
the default setupcontroller
setup assign model on controller. it's implemented like,
setupcontroller: function(controller, model) { controller.set('model', model); }
if not need set custom properties on controller, don't need override it. note: if augmenting additional properties still need call _super
ensure default setupcontroller behaviour executes.
setupcontroller: function(controller, model) { this._super.apply(this, arguments); controller.set('customprop', 'foo'); }
one final caveat, if using linkto
, route not have dynamic segments
, model hook still called. exception makes sense if consider linking /posts
route. model hook has fire else ember has no data display route.
which brings crux of question. there, promise!
in example using linkto
eventsnewroute
. further eventsnewroute
not have dynamic segments ember call model
hook. , controller.set("model", model);
work in setting model on controller
.
the issue use of rendertemplate
. when use render
or {{render}}
helper inside template, getting different controller 1 using. controller different 1 set model
on, hence bug.
a workaround pass controller in options, why rendertemplate
gets controller argument.
rendertemplate: function(controller) { this.render("events-new", { outlet : "events-new", controller: controller }); }
here's updated jsfiddle.
final note: unrelated question, getting warning,
warning: immediate parent route ('application') did not render main outlet , default 'into' option ('events') may not expected
for need read answer. warning, it's wall of text! :)
Comments
Post a Comment