2012-08-16 14 views
11

¿Alguien ha usado ember-data para modelar un árbol de datos?Ember-Data recursive hasMany association

yo asumiría que sería algo así como:

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

Sin embargo, no he sido capaz de conseguir este trabajo que lleva a creer que ser ya sea: 1) Soy simplemente equivocado en la forma en que estoy configurando esto o, 2) actualmente no es posible modelar un árbol usando datos de color ámbar.

Estoy esperando que es lo primero y no lo segundo ...

Por supuesto que podría ser el JSON ... Estoy asumiendo el JSON debe ser de la forma:

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

Cualquier consejo/consejo para este problema sería muy apreciado.

+0

¿Qué no funciona exactamente? ¿Podría agregar algún código a su pregunta para mostrarnos el problema? –

+0

Claro, configuré un ejemplo simple [jsFiddle] (http://jsfiddle.net/heuristocrat/5aqHx/) que muestra cómo creo que debería estar definiendo el modelo y luego haciendo una búsqueda de un nodo raíz e intentando acceder los niños (que es donde las cosas se descomponen). – Heuristocrat

+0

Eso es un violín útil. He tenido problemas similares en un hasMany no recursivo, por lo que estoy interesado en ver cualquier solución. – pjmorse

Respuesta

14

hay varias cosas pequeñas que impiden que su violín a trabajar:

  • la función DS.hasMany pide un String como argumento. No se olvide de las comillas: DS.hasMany('Node')

  • en la definición accesorio, hasMany relaciones no deben ser posteriormente fijados por _ids ni nada. Solo usa el nombre simple. Por ejemplo: { id: 42, children: [2,3], parent_id: 17 }

  • la propiedad length de DS.ManyArray debe acceder usando la función get: root.get('children.length')

  • por defecto, el adaptador del accesorio simula una llamada ajax. La consulta find llenará el registro después de esperar 50 ms. En tu violín, la llamada root.get('children.length') llega demasiado pronto.Se puede configurar el adaptador del accesorio para que haga llamada sincrónica:

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

    O puede cargar datos a la tienda sin ningún adaptador:

    App.store.loadMany(App.Node, [ 
        { id: 1, children: [2, 3] }, 
        { id: 2, children: [], parent_id: 1 }, 
        { id: 3, children: [], parent_id: 1 } 
    ]); 
    
  • y última: Parece que el Ember aplicación debería ser declarado en el ámbito global (sin var), y los modelos Ember-datos deben ser declarados en el ámbito de aplicaciones (en sustitución de var Node = ... por App.Node = ...)

ejemplo completo:

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')); 
+0

asumiendo que App.Node tiene un atributo "nombre", ¿es posible iterar sobre todos los elementos secundarios en una plantilla como esta: {{#each child in controller.children}} {{child.name}} {{/ each}} ? – lipp

+0

¿Cómo eliminarías un nodo sin encontrar una recursión infinita? Actualmente estoy enfrentando este problema. –

-3
No

seguro, pero como en el ejemplo dado en la guía brasa

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

El JSON debe codificar la relación como una matriz de ID:

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

Este didn No funcionaría para mí hasta que configuré la inversa:

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

Parece que no funciona en ember-data 1.0.0-beta.7 (última versión). ¿Alguien resolvió esto en las últimas versiones? – Gorzas