Ember&RSVP:如何解决路由中的嵌套关系's模型函数

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

本文关键字:嵌套 关系 函数 模型 路由 解决 RSVP amp 何解决 Ember      更新时间:2023-09-26

在理解如何解决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 = 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。这就是为什么所有东西都必须声明为async。

您说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测试版10中的一个错误。我试图确定实际问题,但列出了可能导致问题的多种因素。

再一次。谢谢

这里的大多数问题都是围绕着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