简体   繁体   English

Ember&RSVP:如何解决路线模型功能中的嵌套关​​系?

[英]Ember & RSVP: How to resolve nested relations in route's model function?

Having problems to understand how to resolve nested models in ember. 在了解如何解决ember中的嵌套模型时遇到问题。 Damn. 该死的。

I don't know if it's a common approach but I don't want my controllers or components care about asynchronicity at all. 我不知道这是否是一种常见的方法,但是我根本不希望我的控制器或组件完全关心异步性。 Therefore it's necessary to resolve everything needed in my routes. 因此,有必要解决我的路线中所需的一切。

My current approach does not work for nested relations (I'm describing it in the comments). 我当前的方法不适用于嵌套关系(我在评论中对其进行了描述)。

First some model definitions: 首先是一些模型定义:

var Project = DS.Model.extend({
    name: DS.attr("string"),
    tasks: DS.hasMany("task", {async: true}),
    // ...
});

var Task = DS.Model.extend({
    name: DS.attr("string"),
    documentation: DS.belongsTo("task_documentation", {async: true}),
    // ...
});

var TaskDocumentation = DS.Model.extend({
    lastEditor: DS.attr("string")
    // ...
});

ProjectRoute: ProjectRoute:

ProjectRoute = Em.Route.extend({
    model: function () {
        var project;
        return this.store.find("project", {name: "foo"}).then(function (resolvedProject) {
            project = resolvedProject.objectAt(0);
            return resolvedProject.get("tasks");
        }).then(function (resolvedTasks) {
            console.log("For some reason nothing left to do to resolve tasks: " 
                    + project.get("tasks").objectAt(0).get("name"));

            // Collect documentation
            var docu = []
            project.get("tasks").forEach(function (task, index) {
                docus[i] = task.get("documentation");
            });
            return Em.RSVP.all(docus);
        }).then(function (resolvedDocus) {
            // docus are resolved but not attached to project.
            console.log(project.get("tasks")
                   .objectAt(0)
                   .get("documentation")
                   .get("lastEditor")); // "undefined"

            // Setting documentation for each task manually does not help:
            project.get("tasks").forEach(function(task, index) {
                task.set("documentation", resolvedDocus.objectAt(index));
            });
            console.log(project.get("tasks")
                   .objectAt(0)
                   .get("documentation")
                   .get("lastEditor")); // still undefined

            return project;
        });
    }
});

I'm currently using Ember 1.7.0 with Ember Data 1.0.0-beta.10 我目前正在将Ember 1.7.0与Ember Data 1.0.0-beta.10结合使用

I guess there's a much easier way. 我想有一个更简单的方法。 Hope you guys can give me a hint. 希望你们能给我提示。 Thanks in advance! 提前致谢!

UPDATE: 更新:

Thank you for input KingPin! 感谢您输入KingPin!

An important detail I totally forgot to mention is that I'm using FixturesAdaptor right now. 我完全忘记提及的一个重要细节是我现在正在使用FixturesAdaptor。 That's why everything had to be declared async. 这就是为什么所有内容都必须声明为异步的原因。

You said the collection returned by find did not define tasks. 您说find返回的集合没有定义任务。 That's not the case. 事实并非如此。 Everything is resolved correctly. 一切都正确解决了。 The tasks are available. 任务可用。 Even the documentation for each task can be accessed. 甚至可以访问每个任务的文档。

// ...
}).then(function (resolvedDocus) {
    // resolvedDocus have been resolved. I simply cant't attach them to project's tasks
    console.log(resolvedDocus.firstObject.lastEditor); // "Mr. Foo"

});

What I want to accomplish is to return a single project whose properties are directly accessible. 我要完成的工作是返回一个可以直接访问其属性的项目。 At the moment I could create something like model.project , model.tasks , model.taskDocs but when I set project.someTask's documentation, nothing happens. 目前,我可以创建诸如model.projectmodel.tasksmodel.taskDocs类的model.project ,但是当我设置project.someTask的文档时,什么也没发生。

Another Update (cause I'm stupid) 另一个更新(因为我很愚蠢)

There's a typo. 有错别字。

var project;
return this.store.find("project", {name: "foo"}).then(function (resolvedProject) {
    project = resolvedProject.objectAt(0);
    // This of course returns a collection.
    return resolvedProject.get("tasks");
    // I meant...
    return resolvedProject.objectAt(0).get("tasks");

The problem still is the same. 问题仍然是相同的。 Sorry if that caused confusion. 对不起,如果引起混乱。

SOLVED 解决了

It turned out to be a bug in Ember-Data 1.0 beta 10. I tried to identify the actual issue but there are multiple things listed that could have caused the problem. 事实证明,这是Ember-Data 1.0 beta 10中的一个错误。我试图确定实际的问题,但是列出了很多可能导致此问题的原因。

Once again. 再来一次。 Thanks! 谢谢!

Most of your issues here resolve around the fact that your find returns a collection, which won't have tasks defined on it (I'm specifically referring to resolvedProject.get('tasks') ) so you never resolve tasks. 您的大多数问题都在这里解决,因为您的find返回了一个集合,该集合没有定义任何tasks (我专门指的是resolvedProject.get('tasks') ),因此您永远无法解决任务。

ProjectRoute = Em.Route.extend({
    model: function () {
        var project;
        return this.store.find("project", {name: "foo"}).then(function (resolvedProjects) {
            // resolvedProjects is a collection, 
            // but let's assume your api only returns a single project
            project = resolvedProject.objectAt(0);
            return project.get("tasks");
        }).then(function (resolvedTasks) {
            // this was empty because you didn't grab the tasks off a project
            console.log(project.get("tasks.firstObject.name"));

            var documents = resolvedTasks.getEach('documentation');
            return Em.RSVP.all(documents);
        });
    }
});

Example: http://emberjs.jsbin.com/sonane/1/edit 示例: http//emberjs.jsbin.com/sonane/1/edit

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM