2012-04-01 14 views
10

Soy nuevo en BackboneJS y estoy atascado con relaciones anidadas usando Backbone-relational Model con RequireJS -Creo que me encontré con problemas circulares. ¡Cualquier ayuda será muy apreciada!Creación de modelos anidados con backboneJS + backbone-relational + requireJS

tengo el siguiente modelo y recogida:

/* Module Model at models/module*/ 
define([ 
'jquery', 
'underscore', 
'backbone', 
'backboneRelational', 
], function($, _, Backbone) { 

    var ModuleModel = Backbone.RelationalModel.extend({ 

     urlRoot: 'api/module', 
     _radius: 50, 
     relations: [{ 
      type: Backbone.HasMany, 
      key: 'children', 
      relatedModel: 'ModuleModel', 
      collectionType: 'ModuleCollection', 
      reverseRelation: { 
       key: 'parent_id', 
       includeInJSON: 'id' 
      } 
     }], 
     url: function() { 
      return this.id? 'api/module/' + this.id : 'api/module'; 
     } 
    }); 
    return ModuleModel; 
}); 

/* Module Collection */ 
define([ 
'jquery', 
'underscore', 
'backbone', 
'models/module' 
], function($, _, Backbone, ModuleModel) { 

    var ModuleCollection = Backbone.Collection.extend({ 

     model: ModuleModel, 
     url: 'api/modules' 
    }); 

    return ModuleCollection; 
}); 

Cuando inicializar el objeto ModuleModel, que arroja el siguiente error:

Relation=child; no model, key or relatedModel (function(){ parent.apply(this, arguments); }, "children", undefined) 

¿Me podría apuntar a la dirección correcta?

+0

Similar a http://stackoverflow.com/questions/9225640/how-to-represent-uml-relations-with-backbone-relational –

Respuesta

4

Esto parece un problema de alcance. Durante la inicialización del ModuleModel quiere crear una relación hasMany consigo mismo, pero no puede encontrarse a sí misma y que le dará pena en forma de dicho error:

http://jsfiddle.net/yNLbq

Una vez que el objeto es accesible desde la corriente cosas alcance empiezan a trabajar a cabo:

http://jsfiddle.net/jDw5e

una posible solución sería dar modelos y recogida de un espacio de nombres para sí que se puede llegar desde el ámbito actual.

Espero que esto ayude.

2

Desde un comentario en la columna vertebral v0.5.0-relational.js (línea 375):
// 'exportaciones' debería ser el objeto global, donde 'relatedModel' se puede encontrar en caso de tratarse de una cadena.

Si necesita el valor especial 'exports' como una dependencia en su llamada de definición, y luego coloca su módulo en el objeto de exportación antes de regresar, puede hacer referencia a ese módulo como cadena o como miembro de exportaciones.

en ModuleModel.js:

define(['exports', 'use!backbone', 'use!backbone-relational'], function(exports, Backbone) { 
    var ModuleModel = Backbone.RelationalModel.extend({ 
    relations: [ 
     { 
     type: Backbone.HasMany, 
     key: 'groups', 
     relatedModel: 'ModuleModel', 
     collectionType: 'ModuleCollection' 
     } 
    ] 
    }); 
    exports.ModuleModel = ModuleModel; 
    return ModuleModel; 
}); 

y en ModuleCollection.js:

define(['exports', 'use!backbone'], function(exports, Backbone) { 
    var ModuleCollection = Backbone.RelationalModel.extend({ 
    url: '/api/v1/module/'; 
    model: exports.ModuleModel; 
    }); 
    exports.ModuleCollection = ModuleCollection; 
    return ModuleCollection; 
}); 
+3

exportaciones no es algo que usted defina; es tratado especialmente por require. Requirejs crea un diccionario y lo pasa a cualquier definición que requiera 'exportaciones' para que pueda compartir valores entre definir llamadas. No necesita crear un archivo ni hacer nada especial, solo use el nombre mágico 'exports' como una de sus dependencias. – dokkaebi

+0

Por favor, ¿me pueden decir qué módulo debería instanciar? ambos o solo uno, y si solo uno, ¿cuál entre ModuleCollection y ModuleModel? –

+0

Usando el código que publiqué, tanto ModuleModel como ModuleCollection deberían funcionar como se esperaba. En otro lugar de su código, puede hacer algo como 'require (['ModuleCollection', 'ModuleModel'], function (ModuleCollection, ModuleModel) {myModules = new ModuleCollection(); myModel = new ModuleModel ({/ * algunos valores * /}); myModules.add (myModel);} '. Puede ser útil ver lo que estás tratando de hacer: si esto no funciona como se esperaba, podrías abrir una nueva pregunta y vincularla aquí. – dokkaebi

3

me encontré con este problema desde aquí: RequireJS + BackboneRelational + Self-Referential. Parece que heredó algunos de sus problemas de este hilo, así que pensé que podría agregar mi moneda de diez centavos.

En primer lugar, ya que está utilizando RequireJS, no hay variables globales. No puede simplemente proporcionar el nombre del objeto, debe proporcionar las referencias de objeto reales para relatedModel y collectionType.

su problema más difícil es que ModuleModel 's relatedModel es en realidad ModuleModel en sí, que no se define cuando se asigna a relatedModel (utilizando el modelo AMD). Debe aplazar la asignación hasta que se haya asignado ModuleModel.

Finalmente, debe resolver la referencia circular. dokkaebi está en el camino correcto cuando sugiere usar exports, pero su implementación realmente usa incorrectamente exports.Al exportar, adjunte el objeto directamente al exports como sugiere, pero cuando lo importe necesita hacer referencia al módulo para usarlo, no al exports.

Esto debería funcionar:

ModuleModel.js

define(['exports', 'ModuleCollection'], function (exports, Module) { 
    'use strict'; 

    var ModuleModel = Backbone.RelationalModel.extend({ 
     urlRoot: 'api/module', 
     _radius: 50, 
     relations: [{ 
      type: Backbone.HasMany, 
      key: 'children', 
      // ModuleModel is undefined; this line is useless 
      // relatedModel: ModuleModel, 
      // no globals in require; must use imported obj ref 
      collectionType: Module.Collection, 
      reverseRelation: { 
       key: 'parent_id', 
       includeInJSON: 'id' 
      } 
     }], 
     url: function() { 
      return this.id? 'api/module/' + this.id : 'api/module'; 
     } 
    }); 

    // Now that `ModuleModel` is defined, we can supply a valid object reference: 
    ModuleModel.prototype.relations[0].relatedModel = ModuleModel; 

    // Attach `Model` to `exports` so an obj ref can be obtained elsewhere 
    exports.Model = ModuleModel; 
}); 

ModuleCollection.js

define(['exports', 'ModuleModel'], function(exports, Module) { 
    'use strict'; 

    var ModuleCollection = Backbone.Collection.extend({ 
     // must reference the imported Model 
     model: Module.Model, 
     url: 'data.php' // <-- or wherever 
    }); 

    // Attach `Collection` to `exports` so an obj ref can be obtained elsewhere 
    exports.Collection = ModuleCollection; 
}); 

main.js

define(['ModuleCollection'], function(Module) { 
    'use strict'; 

    var modules = new Module.Collection(); 
    modules.fetch().done(function() { 
     modules.each(function(model) { 
     console.log(model); 
     }); 
    }); 

}); 
2

Me encontré con el mismo problema hace un tiempo y seguí el enfoque utilizado por Andrew Ferk para su pregunta: Backbone-relational submodels with RequireJS. El problema surge porque está definiendo modelos como Require modules por lo que no existen en el ámbito global, donde backbone-relational puede buscarlos. En lugar de utilizar el alcance global (supera el objetivo de Require) o las exportaciones (un poco complicado con las relaciones), puede definir un alcance para sus modelos y decirle a backbone-relational que busque modelos en él, con addModelScope().

//modelStore.js - A scope in which backbone-relational will search for models 
//Defined separately so you can access 'modelStore' directly for your models instead of requiring 'app' every time. 
define(['app'], function(app) { 
    app.modelStore = {}; 
    Backbone.Relational.store.addModelScope(app.modelStore); 
    return app.modelStore; 
} 

Por cierto que debe calzar su dependencia de la espina dorsal y no es necesario requerir jQuery y subrayado por ello.

//ModuleModel (The ModuleModel module. Nice.) 
define(['modelStore', 'backbone', 'backboneRelational'], function(modelStore, Backbone { 
    modelStore.ModuleModel = Backbone.RelationalModel.extend({ 
     relations: [ 
     { 
      type: Backbone.HasMany, 
      key: 'groups', 
      relatedModel: 'ModuleModel', //Not modelStore.ModuleModel 
      collectionType: 'ModuleCollection' 
     } 
     ] 
    }); 
    return modelStore.ModuleModel; 
}); 

Ya es tarde para esto, pero espero que ayude a los demás.

Cuestiones relacionadas