任务:
在灯箱中打开一个表单以创建一个新的“事件”;打开的表单应该可以添加书签。
障碍:
- 有使用
{{action}}
标签打开灯箱的示例,但找不到在自己的路径中打开的灯箱。 - 有很多使用旧版本 ember.js 的示例。
- 与 ember-data 和 REST 相关的文档并不多(我知道,我知道......它还没有“准备好生产”)。
问题:
表单中的字段没有绑定(bind)到支持模型,因此“null”被发布到我的 servlet(Spring Controller )。
我的第一次迭代与final outcome (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
才能正确设置模型?
最后,由于我很难找到一个功能齐全的示例,因此我希望使其易于访问(并希望发现改进)。
这是 fiddle :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/ (尝试模仿我学到的东西,但将 add-new 变形为新路线)
- Writing a LightboxView causes problems / Integrating DOM Manipulating jQuery-Plugins makes actions unusable (灯箱“示例”)
- Dependable views in Ember (另一个灯箱“示例”,但没有灯箱打开的路线)
最佳答案
Why does the setupController function need to call controllerFor in order to properly set up the model?
Ember 使 URL 成为其约定中不可或缺的一部分。这意味着应用程序的状态
由它所在的路由表示。您已经正确理解了大部分内容。但有一些微妙的细微差别,我将在下面澄清。
首先考虑具有以下 URL 的应用,
- /posts - 显示博客文章列表。
- /posts/1 - 显示单个博客文章。
假设点击 /posts
列表中的帖子会将您带到 /posts/1
。
在这种情况下,用户可以通过两种方式查看 /posts/1
上的帖子。
- 前往
/posts
并点击第 1 篇帖子。 - 通过输入
/posts/1
、通过书签等
在这两种情况下,/posts/1
的 PostRoute
将需要与 Post
id 1 对应的模型。
首先考虑直接输入场景。要提供一种查找 id=1 帖子模型的方法,您可以使用,
model: function(params) {
return App.Post.find(params.post_id);
}
您的帖子模板将获取模型,并且可以使用其属性进行渲染。
现在考虑第二种情况。单击 id=1 的帖子会将您带到 /posts/1
。为此,您的模板将使用 linkTo
,如下所示。
{{#linkTo 'post' post}} {{post.title}} {{/linkTo}}
在这里,您将 post
模型传递给 linkTo
帮助器。然后,它将帖子的数据序列化为 URL,即:- '/posts/1'。当您单击此链接时,Ember 意识到它需要渲染 PostRoute
但它已经有了 post 模型。因此它会跳过模型钩子(Hook)并直接调用setupController
。
默认的setupController
设置为简单地在 Controller 上分配模型。它的实现是为了做类似的事情,
setupController: function(controller, model) {
controller.set('model', model);
}
如果您不需要在 Controller 上设置自定义属性,则无需覆盖它。注意:如果您使用其他属性对其进行扩充,您仍然需要调用 _super
以确保执行默认的 setupController 行为。
setupController: function(controller, model) {
this._super.apply(this, arguments);
controller.set('customProp', 'foo');
}
最后需要注意的是,如果您使用 linkTo
并且路由没有动态段
,则仍会调用模型 Hook 。如果您认为您正在链接到 /posts
路由,则此异常是有意义的。然后模型钩子(Hook)必须触发,否则 Ember 没有数据来显示路线。
这让我们找到了您问题的关键。快到了,我保证!
在您的示例中,您使用 linkTo
访问 EventsNewRoute
。此外,您的 EventsNewRoute 没有动态段,因此 Ember 会调用 model Hook 。 controller.set("model", model);
确实可以在 controller
上设置模型。
问题与您对 renderTemplate
的使用有关。当您在模板中使用 render
或 {{render}}
帮助器时,您实际上获得了与您正在使用的 Controller 不同的 Controller 。该 Controller 与您设置模型的 Controller 不同,因此存在错误。
解决方法是在选项中传递 Controller ,这就是 renderTemplate
将此 Controller 作为参数的原因。
renderTemplate: function(controller) {
this.render("events-new", {
outlet : "events-new", controller: controller
});
}
这是更新的 jsfiddle .
最后注意:与此问题无关,您收到警告,
WARNING: The immediate parent route ('application') did not render into the main outlet and the default 'into' option ('events') may not be expected
为此,您需要阅读此answer 。警告,这是另一面文字墙! :)
关于ember.js - Ember、Ember-data 和 jquery-ui.dialog, "Oh my!",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17820125/