2014-11-09 1 views
1

Возникли проблемы, чтобы понять, как разрешать вложенные модели в ember. Черт.Ember & RSVP: Как разрешить вложенные отношения в функции модели маршрута?

Я не знаю, является ли это обычным подходом, но я не хочу, чтобы мои контроллеры или компоненты заботились об асинхронности вообще. Поэтому необходимо разрешить все, что необходимо на моих маршрутах.

Мой текущий подход не работает для вложенных отношений (я описываю его в комментариях).

Первые несколько определений модели:

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 данных 1.0.0-beta.10

Я думаю, есть намного более простой способ. Надеюсь, вы, ребята, можете дать мне подсказку. Заранее спасибо!

UPDATE:

Спасибо за входной 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.project, model.tasks, model.taskDocs, но когда я устанавливаю документацию project.someTask, ничего не происходит.

Другой Update (потому что я глуп)

Там опечатка.

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

Проблема по-прежнему та же. Извините, если это вызвало путаницу.

решаемые

Оказалось, что ошибка в угасающий-Data 1.0 бета 10. Я попытался определить реальную проблему, но есть несколько вещей, которые могли бы перечисленные вызвавшие проблему.

Еще раз. Благодаря!

+0

У вас есть контроль над API? Наличие этих асинхронных связей, а затем принудительное их принудительное получение всех сразу кажется пустой тратой вызовов на ваш сервер. Похоже, это хорошая возможность использовать встроенные записи и пропустить асинхронную работу. – Kingpin2k

+0

Извините, что забыл рассказать. Обновлен вопрос. –

+0

Не могли бы вы обновить вопрос с тем, как выглядит ваше полное обещание, и областями, которые не показывают то, что вы ожидаете? – Kingpin2k

ответ

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