任务:
在灯箱中打开表单以创建新的";事件";;打开的表单应该是可添加书签的。
路障:
- 有一些使用
{{action}}
标记打开灯箱的示例,但找不到在自己的路径中打开的灯箱 - 有很多使用旧版本ember.js的例子
- 没有太多与ember数据和REST相关的文档(我知道,我知道……它还没有"生产就绪")
问题是:
表单中的字段没有与支持模型绑定;空";正在被发布到我的servlet(一个Spring控制器)中。
我的第一次迭代离最终结果(jsfiddle)不远。最终使其工作的东西交换:
EP.EventsNewRoute = Ember.Route.extend({
...
setupController : function(controller, model) {
controller.set("model", model);
},
...
});
为此:
EP.EventsNewRoute = Ember.Route.extend({
...
setupController : function(controller, model) {
this.controllerFor("events-new").set("model", model);
},
...
});
问题是:
为什么setupController函数需要调用controllerFor
才能正确设置模型?
最后,由于我很难找到一个功能齐全的示例,我想让它变得容易访问(并希望发现改进)。
小提琴在这儿:http://jsfiddle.net/6thJ4/1/
以下是一些片段。
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); // What does this do differently?
},
...
});
EP.EventsNewController = Ember.ObjectController.extend({
save : function() {
this.get("content.transaction").commit(); // "content.store" would commit _everything modified_, we only have one element changed, so only "content.transaction" is necessary.
}
});
EP.EventsNewView = Ember.View.extend({
...
});
EP.Event = DS.Model.extend({
name : DS.attr("string"),
hostName : DS.attr("string")
});
资源:
- http://emberjs.com/guides/routing/setting-up-a-controller/
- http://emberjs.com/guides/getting-started/toggle-all-todos/(试图模仿我学到的东西,但将添加新的路线变形为新的路线)
- 编写LightboxView会导致问题/集成DOM操作jQuery插件会导致操作不可用(lightbox"example")
- Ember中的可靠视图(另一个灯箱"示例",但没有灯箱打开的路线)
为什么setupController函数需要调用controllerFor才能正确设置模型?
Ember使URL成为其约定中不可或缺的一部分。这意味着应用程序的state
由它所在的路由表示。但有一些细微的差别,我将在下面澄清。
首先考虑一个具有以下URL的应用程序,
- /posts-显示博客文章列表
- /posts/1-显示单个博客文章
比如说,在/posts
点击列表中的一篇文章,就会进入/posts/1
。
在这种情况下,用户可以通过两种方式在/posts/1
上查看帖子。
- 转到
/posts
并单击第一个帖子 - 通过键入
/posts/1
、书签等
在这两种情况下,/posts/1
的PostRoute
将需要对应于Post
id 1的模型。
首先考虑直接键入场景。为了提供一种查找id=1 post模型的方法,您可以使用
model: function(params) {
return App.Post.find(params.post_id);
}
您的post模板将获得模型,并可以使用其属性进行渲染。
现在考虑第二种情况。点击id=1的帖子,进入/posts/1
。要做到这一点,您的模板将像这样使用linkTo
。
{{#linkTo 'post' post}} {{post.title}} {{/linkTo}}
在这里,您将把post
模型传递给linkTo
辅助对象。然后,它将帖子的数据序列化为一个URL,即:-'/posts/1'。当你点击这个链接时,Ember意识到它需要渲染PostRoute
,但它已经有了post模型。因此它跳过模型挂钩,直接调用setupController
。
默认的setupController
设置为简单地在控制器上分配模型。它的实现类似于
setupController: function(controller, model) {
controller.set('model', model);
}
如果您不需要在控制器上设置自定义属性,则不需要覆盖它。注意:如果您正在用其他属性扩充它,则仍然需要调用_super
以确保执行默认的setupController行为。
setupController: function(controller, model) {
this._super.apply(this, arguments);
controller.set('customProp', 'foo');
}
最后一个警告是,如果您使用的是linkTo
,而路由没有dynamic segments
,那么模型钩子仍然被调用。如果您认为您正在链接到/posts
路由,则此异常是有意义的。然后模型挂钩必须开火,否则Ember没有数据显示路线。
这就引出了你问题的症结所在。快到了,我保证!
在您的示例中,您使用linkTo
到达EventsNewRoute
。此外,您的EventsNewRoute
没有动态段,因此Ember确实调用了model
钩子。而CCD_ 27的作用与其说是在CCD_ 28上设置模型。
问题与您使用renderTemplate
有关。当您在模板中使用render
或{{render}}
辅助对象时,您实际上得到了与正在使用的控制器不同的控制器。此控制器与您设置model
的控制器不同,因此出现错误。
解决方法是在选项中传递控制器,这就是renderTemplate
将此控制器作为参数的原因。
renderTemplate: function(controller) {
this.render("events-new", {
outlet : "events-new", controller: controller
});
}
这是一个更新的jsfiddle。
最后一点:与这个问题无关,你得到了警告,
警告:直接父路由("应用程序")未呈现到主出口,并且可能不需要默认的"进入"选项("事件")
为此,你需要阅读这个答案。警告,这是另一面文字墙!:)