ember.js - Ember、Ember-data 和 jquery-ui.dialog, "Oh my!"

标签 ember.js ember-data jquery-dialog

任务:

在灯箱中打开一个表单以创建一个新的“事件”;打开的表单应该可以添加书签。

障碍:

  1. 有使用 {{action}} 标签打开灯箱的示例,但找不到在自己的路径中打开的灯箱。
  2. 有很多使用旧版本 ember.js 的示例。
  3. 与 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")
});

资源:

  1. http://emberjs.com/guides/routing/setting-up-a-controller/
  2. http://emberjs.com/guides/getting-started/toggle-all-todos/ (尝试模仿我学到的东西,但将 add-new 变形为新路线)
  3. Writing a LightboxView causes problems / Integrating DOM Manipulating jQuery-Plugins makes actions unusable (灯箱“示例”)
  4. 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 上的帖子。

  1. 前往 /posts 并点击第 1 篇帖子。
  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 模型。因此它会跳过模型钩子(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/

相关文章:

JQuery 动态对话框 Div

javascript - 如何通过id从hbs中选择元素

Ember.js:如何获取输入元素 ID 以在标签中使用

ember.js - 在 Ember 中的引导模式内渲染表单

ember.js - Ember-Cli 将记录保存到 http-mock 服务器

javascript - 在 JQuery UI 对话框中包含 google 可视化时间线失败

jquery-ui - 覆盖 jQueryUI 对话框默认选项

javascript - 升级到 Ember 1.0 计算属性不再在 View 中工作

javascript - Coffeescript 和 Ember.js 计算属性

javascript - 输入大小的 Ember 全局变量