Рекурсивная ассоциация Ember-Data hasMany

Кто-нибудь использовал данные ember-data для моделирования дерева данных?

Я бы предположил, что это будет что-то вроде:

Node = DS.Model.extend({
    children: DS.hasMany(Node),
    parent:   DS.belongsTo(Node)
});

Тем не менее, я не смог получить эту работу, которая верит в то, что: 1) я просто ошибаюсь в том, как я это настраиваю, или 2) в настоящее время невозможно моделировать дерево с использованием данных ember.

Я надеюсь, что это первая, а не последняя...

Конечно, это может быть JSON... Я предполагаю, что JSON должен иметь форму:

{
    nodes: [
        { id: 1, children_ids: [2,3], parent_id: null },
        { id: 2, children_ids: [], parent_id: 1 },
        { id: 3, children_ids: [], parent_id: 1 }
    ]
}

Приветствуются любые советы/рекомендации по этой проблеме.

Ответ 1

Есть несколько вещей, которые мешают вашей скрипке работать:

  • функция DS.hasMany запрашивает аргумент String. Не забудьте цитаты: DS.hasMany('Node')

  • в определении приспособления, отношения hasMany не должны быть добавлены с помощью _ids или что-либо еще. Просто используйте простое имя. Например: { id: 42, children: [2,3], parent_id: 17 }

  • свойство length DS.ManyArray должно быть доступно с помощью функции get: root.get('children.length')

  • по умолчанию адаптер адаптера имитирует вызов ajax. Запрос find будет заполнять запись после ожидания 50 мс. В вашей скрипке вызов root.get('children.length') приходит слишком рано. Вы можете настроить адаптер адаптера так, чтобы он выполнял синхронный вызов:

    App.store = DS.Store.create({
        revision: 4,
        adapter: DS.FixtureAdapter.create({
            simulateRemoteResponse: false
        })
    });
    

    Или вы можете загружать данные в хранилище без какого-либо адаптера:

    App.store.loadMany(App.Node, [
        { id: 1, children: [2, 3] },
        { id: 2, children: [], parent_id: 1 },
        { id: 3, children: [], parent_id: 1 }
    ]);
    
  • и последний: похоже, приложение Ember должно быть объявлено в глобальной области (no var), а модели данных Ember-данных должны быть объявлены в области приложения (заменяя var Node = ... на App.Node = ...)

Полный пример:

App = Ember.Application.create();

App.store = DS.Store.create({
    revision: 4
});

App.Node = DS.Model.extend({
    children: DS.hasMany('App.Node'),
    parent:   DS.belongsTo('App.Node')
});

App.store.loadMany(App.Node, [
    { id: 1, children: [2, 3] },
    { id: 2, children: [], parent_id: 1 },
    { id: 3, children: [], parent_id: 1 }
]);

var root = App.store.find(App.Node, 1);

alert(root.get('children'));
alert(root.get('children.length'));

Ответ 2

Это не сработало для меня, пока я не настроил инверсию:

App.Node = DS.Model.extend({
    children: DS.hasMany('App.Node', {inverse: 'parent'}),
    parent:   DS.belongsTo('App.Node', {inverse: 'children'}) });

Ответ 3

Не уверен, но, как пример, приведенный в руководстве ember

App.Post = DS.Model.extend({
  comments: DS.hasMany('App.Comment')
});

JSON должен кодировать отношение как массив идентификаторов:

{
  "post": {
    "comment_ids": [1, 2, 3]
  }
}