灰烬& RSVP:如何解决路径模型函数中的嵌套关​​系?

时间:2014-11-09 16:22:26

标签: javascript ember.js ember-data rsvp.js

无法理解如何在ember中解析嵌套模型。该死。

我不知道这是否是一种常见方法,但我不希望我的控制器或组件完全关心异步性。因此,有必要解决我的路线所需的一切。

我当前的方法不适用于嵌套关系(我在评论中对它进行了描述)。

首先是一些模型定义:

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

我目前正在使用Ember 1.7.0和Ember Data 1.0.0-beta.10

我想有一种更简单的方法。希望你们能给我一个暗示。提前谢谢!

更新

感谢您输入KingPin!

我完全忘记提到的一个重要细节是我现在正在使用FixturesAdaptor。这就是为什么一切都必须被声明为异步的原因。

你说find返回的集合没有定义任务。事实并非如此。一切都正确解决了。任务可用。甚至可以访问每个任务的文档。

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

});

我想要完成的是返回一个可直接访问其属性的项目。目前我可以创建类似model.projectmodel.tasksmodel.taskDocs的内容,但是当我设置project.someTask的文档时,没有任何反应。

另一次更新(因为我很蠢)

有一个错字。

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

问题仍然是一样的。对不起,如果这引起了混乱。

解决

原来是Ember-Data 1.0 beta 10中的一个错误。我试图找出实际问题,但列出的内容可能会导致问题。

再一次。谢谢!

1 个答案:

答案 0 :(得分:2)

此处的大部分问题都解决了这样一个事实:您的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);
        });
    }
});

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