2012-04-01 15 views
10

Ich bin neu in BackboneJS und ich bin stecken mit verschachtelten Beziehungen mit Backbone-relationalem Modell mit RequireJS -Ich glaube, ich lief in kreisförmigen Fragen. Jede Hilfe wird sehr geschätzt!Erstellen geschachtelter Modelle mit BackboneJS + Backbone-relational + requireJS

Ich habe folgendes Modell und Sammlung:

/* 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; 
}); 

Wenn ich das Objekt ModuleModel initialisieren, wirft es den folgenden Fehler:

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

Könnten Sie mir zeigen in die richtige Richtung?

+0

Ähnlich wie http://stackoverflow.com/questions/9225640/how-to-represent-uml-relations-with-backbone-relational –

Antwort

4

Dies sieht wie ein Problem mit dem Scoping aus. Während der Initialisierung von ModuleModel will er eine hasMany Beziehung mit sich selbst schaffen, aber es kann sich nicht finden und es wird Ihnen in Form Trauer des Fehlers:

http://jsfiddle.net/yNLbq

Sobald das Objekt ist erreichbar von der aktuellen Umfang Dinge beginnen zu arbeiten:

http://jsfiddle.net/jDw5e

eine mögliche Lösungsmodell und Sammlung wäre für mich einen Namensraum zu geben, die aus dem aktuellen Bereich erreicht werden können.

Hoffe, das hilft.

2

Von einem Kommentar in Backbone-relational.js v0.5.0 (Linie 375):
// ‚Ausfuhren‘ sollte das globale Objekt, wo ‚relatedModel‘ auf als String, wenn gegeben gefunden werden kann.

Wenn Sie den speziellen Wert 'exports' als Abhängigkeit in Ihrem Define-Aufruf benötigen und dann Ihr Modul auf das exports-Objekt setzen, bevor Sie zurückkommen, können Sie dieses Modul als Zeichenfolge oder Exportelement referenzieren.

in 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; 
}); 

und in 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

Exporte ist nicht etwas, was Sie definieren; es wird speziell nach Bedarf behandelt. Requirejs erstellt ein Wörterbuch und übergibt es an alle Definitionen, die "Exporte" erfordern, damit Sie Werte zwischen definierten Aufrufen teilen können. Sie müssen weder eine Datei erstellen noch etwas Spezielles tun - verwenden Sie einfach den magischen Namen "exports" als eine Ihrer Abhängigkeiten. – dokkaebi

+0

Können Sie mir bitte sagen, welches Modul ich instanziieren soll? beide oder nur eine, und wenn nur eine, die zwischen ModuleCollection und ModuleModel? –

+0

Mithilfe des von mir veröffentlichten Codes sollten sowohl ModuleModel als auch ModuleCollection wie erwartet funktionieren. An anderer Stelle im Code, vielleicht tun Sie so etwas wie 'require ([ 'ModuleCollection', 'ModuleModel'], Funktion (ModuleCollection, ModuleModel) {myModules = new ModuleCollection(); MyModel = new ModuleModel ({/ * einige Werte * /}); myModules.add (MyModel);} 'es könnte helfen, zu sehen, was Sie zu tun versuchen - wenn dies nicht wie erwartet funktioniert, können Sie hier eine neue Frage und Link öffnen könnten.. – dokkaebi

3

ich auf dieses Problem kam von hier: RequireJS + BackboneRelational + Self-Referential. Er scheint einige seiner Probleme von diesem Thread geerbt zu haben, also dachte ich, ich könnte meinen Groschen hinzufügen.

Erstens, da Sie RequireJS verwenden, gibt es keine globalen Variablen. Sie können nicht einfach den Namen des Objekts angeben. Sie müssen tatsächliche Objektreferenzen für relatedModel und collectionType angeben.

Ihr heikelsten Problem ist, dass ModuleModel ‚s relatedModel tatsächlich ModuleModel selbst, die definiert wird, nicht, wenn Sie es relatedModel (mit Hilfe des AMD-Modell). Sie müssen die Zuweisung verschieben, bis nach ModuleModel zugewiesen ist.

Schließlich müssen Sie den Zirkelverweis auflösen. Dokkaebi ist auf dem richtigen Weg, wenn er vorschlägt, exports zu verwenden, aber seine Implementierung missbraucht tatsächlich exports.Beim Export, schließen Sie das Objekt direkt an exports, wie er sagt, aber wenn Sie es importieren müssen Sie das Modul verweisen, es zu benutzen, nicht exports.

Dies sollte funktionieren:

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

Ich lief in das gleiche Problem eine Weile zurück und folgte den von Andrew Ferk verbreiteten Ansatz für seine Frage: Backbone-relational submodels with RequireJS. Das Problem entsteht, weil man Modelle ist definiert, als Module erfordern, so dass sie auf dem globalen Bereich nicht existieren, wo Rückgrat relationale für sie suchen. Stattdessen globale Reichweite der Verwendung (schlägt den Zweck erforderlich) oder die Exporte (etwas schwierig mit den Beziehungen), können Sie einen Bereich für Ihre Modelle definieren und sagen Backbone-relationale für Modelle darin zu suchen, mit 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; 
} 

Durch die Art und Weise Sie Ihre Backbone Abhängigkeit Shim sollte und nicht brauchen, um jQuery und Unders dafür benötigen.

Ein bisschen zu spät jetzt aber hoffe, es hilft anderen.

Verwandte Themen