Ember,Ember-data和jquery-ui.dialog,“哦,我的!”

时间:2013-07-23 20:11:14

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

任务:

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

路障:

  1. 有使用{{action}}标签打开灯箱的示例,但找不到在自己路线中打开的灯箱。
  2. 有许多使用旧版本的ember.js的例子。
  3. 没有很多与ember-data和REST相关的文档(我知道,我知道......它不是“生产就绪”)。
  4. 问题:

    表单中的字段没有绑定到支持模型,因此“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/

    以下是几个片段。

    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(另一个灯箱“示例”,但没有灯箱开放的路线)

1 个答案:

答案 0 :(得分:2)

  

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

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

首先考虑具有以下网址的应用

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

点击/posts列表中的帖子,即可转到/posts/1

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

  1. 转到/posts并点击第1个帖子。
  2. 输入/posts/1,通过书签等
  3. 在这两种情况下,PostRoute的{​​{1}}都需要与/posts/1 id 1对应的模型。

    首先考虑直接输入方案。要提供一种查找id = 1 post模型的方法,您可以使用

    Post

    您的帖子模板将获取模型,并且可以使用它的属性进行渲染。

    现在考虑第二种情况。点击ID = 1的帖子即可转到model: function(params) { return App.Post.find(params.post_id); } 。为此,您的模板将使用/posts/1这样的内容。

    linkTo

    在这里,您将{{#linkTo 'post' post}} {{post.title}} {{/linkTo}} 模型传递给post帮助程序。然后它将帖子的数据序列化为URL,即: - '/ posts / 1'。当您单击此链接时,Ember意识到它需要呈现linkTo但它已经具有帖子模型。所以它跳过模型钩子并直接调用PostRoute

    默认setupController设置为简单地在控制器上分配模型。它被实现为做类似的事情,

    setupController

    如果您不需要在控制器上设置自定义属性,则无需覆盖它。注意:如果您使用其他属性对其进行扩充,则仍需要调用setupController: function(controller, model) { controller.set('model', model); } 以确保执行默认的setupController行为。

    _super

    最后一点需要注意,如果您使用的是setupController: function(controller, model) { this._super.apply(this, arguments); controller.set('customProp', 'foo'); } 且路由没有linkTo,则仍会调用模型挂钩。如果您认为链接到dynamic segments路由,则此异常有意义。然后模型钩子必须触发,否则Ember没有数据显示路线。

    这将我们带到你问题的症结所在。差不多在那里,我保证!

    在您的示例中,您使用/posts来访问linkTo。此外,您的EventsNewRoute没有动态细分,因此Ember会调用EventsNewRoute挂钩。 model确实可以在controller.set("model", model);上设置模型。

    问题与您使用controller有关。在模板中使用renderTemplaterender帮助程序时,您实际上会获得与您正在使用的控制器不同的控制器。此控制器与您设置{{render}}的控制器不同,因此也就是错误。

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

    renderTemplate

    这是一个更新的jsfiddle

    最后注意:与此问题无关,您收到警告,

      

    警告:直接父路线('申请')没有呈现到主要出口,并且可能不会预期默认的'进入'选项('事件')

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