【问题标题】:Ember, Ember-data, and jquery-ui.dialog, "Oh my!"Ember、Ember-data 和 jquery-ui.dialog,“哦,我的!”
【发布时间】:2013-07-24 21:50:54
【问题描述】:

任务:

在灯箱中打开表单以创建新的“事件”;打开的表单应该是可收藏的。

路障:

  1. 有一些使用{{action}} 标签打开灯箱的示例,但找不到以自己的路径打开的灯箱。
  2. 有很多使用旧版本 ember.js 的示例。
  3. 没有很多与 ember-data 和 REST 相关的文档(我知道,我知道......它还没有“准备好生产”)。

问题:

表单中的字段没有绑定到支持模型,因此“null”被发布到我的 servlet(一个 Spring 控制器)。

我的第一次迭代与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 才能正确设置模型?


最后,由于我很难找到一个功能齐全的示例,我想让它易于访问(并希望发现改进)。

这是小提琴:http://jsfiddle.net/6thJ4/1/

这里有一些sn-ps。

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")
});

资源:

  1. http://emberjs.com/guides/routing/setting-up-a-controller/
  2. http://emberjs.com/guides/getting-started/toggle-all-todos/(试图模仿我学到的东西,但将新增内容转变为新路线)
  3. Writing a LightboxView causes problems / Integrating DOM Manipulating jQuery-Plugins makes actions unusable(灯箱“示例”)
  4. Dependable views in Ember(另一个灯箱“示例”,但没有打开灯箱的路线)

【问题讨论】:

  • 您可能想澄清这个问题。您已经概述了问题的背景,但其中似乎没有直接的问题。
  • @Darshan,感谢您的建议。我已经对其进行了修改,使问题更加突出。请注意,JavaScript sn-p 中也有一些基于上下文的问题。

标签: ember.js ember-data jquery-dialog


【解决方案1】:

为什么 setupController 函数需要调用 controllerFor 才能正确设置模型?

Ember 使 URL 成为其约定中不可或缺的一部分。这意味着您的应用程序的state 由它所在的路由表示。您已经正确理解了其中的大部分内容。但是有一些细微的差别,我将在下面澄清。

首先考虑一个具有以下 URL 的应用,

  • /posts - 显示博客文章列表。
  • /posts/1 - 显示一篇博文。

然后说点击列表中/posts 的帖子会将您带到/posts/1

在这种情况下,用户可以通过两种方式查看/posts/1 的帖子。

  1. 转至/posts 并点击第一个帖子。
  2. 通过输入/posts/1、通过书签等方式。

在这两种情况下,/posts/1PostRoute 将需要与 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 模型。所以它跳过了模型钩子,直接调用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 挂钩。而controller.set("model", model); 确实可以在controller 上设置模型。

问题与您对renderTemplate 的使用有关。当您在模板中使用 render{{render}} 助手时,您实际上获得了与您正在使用的控制器不同的控制器。此控制器与您设置 model 的控制器不同,因此存在错误。

一种解决方法是在选项中传递控制器,这就是renderTemplate 将此控制器作为参数的原因。

renderTemplate: function(controller) {
  this.render("events-new", {
    outlet : "events-new", controller: controller
  });
}

这是更新后的jsfiddle

最后说明:与此问题无关,您会收到警告,

警告:直接父路由(“应用程序”)未呈现到主出口,默认的“进入”选项(“事件”)可能不是预期的

为此,您需要阅读此answer。警告,这是另一堵文字墙! :)

【讨论】:

  • 这个深入的回应推动了我的项目前进!谢谢,好心!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多