2012-04-01 32 views
10

Tôi mới dùng BackboneJS và tôi bị mắc kẹt với các quan hệ lồng nhau sử dụng Mô hình quan hệ Backbone với RequireJS -Tôi nghĩ rằng tôi đã chạy vào các vấn đề vòng tròn. Bất kỳ trợ giúp sẽ được đánh giá cao!Tạo các mô hình lồng nhau với backboneJS + backbone-relational + requireJS

Tôi có theo mô hình và bộ sưu tập:

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

Khi tôi khởi tạo ModuleModel đối tượng, nó ném các lỗi sau:

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

Ông có thể chỉ cho tôi đi đúng hướng?

+0

Tương tự như http://stackoverflow.com/questions/9225640/how-to-represent-uml-relations-with-backbone-relational –

Trả lời

4

Điều này trông giống như vấn đề phạm vi. Trong thời gian khởi của ModuleModel nó muốn tạo ra một mối quan hệ hasMany với chính nó, nhưng nó không thể tìm thấy chính nó và nó sẽ cho bạn đau buồn dưới hình thức cho biết lỗi:

http://jsfiddle.net/yNLbq

Khi các đối tượng có thể truy cập từ hiện tại phạm vi mọi thứ bắt đầu làm việc ra:

http://jsfiddle.net/jDw5e

một giải pháp có thể sẽ được cung cấp cho các mô hình và bộ sưu tập một không gian tên cho bản thân mà có thể đạt được từ phạm vi hiện tại.

Hy vọng điều này sẽ hữu ích.

2

Từ nhận xét trong backbone-relational.js v0.5.0 (dòng 375):
// 'xuất' phải là đối tượng chung có thể tìm thấy 'relatedModel' nếu được cho dưới dạng chuỗi.

Nếu bạn yêu cầu giá trị 'xuất' đặc biệt dưới dạng phụ thuộc trong lệnh gọi xác định, sau đó đặt mô-đun của bạn vào đối tượng xuất trước khi bạn quay trở lại, bạn có thể tham chiếu mô-đun đó dưới dạng chuỗi hoặc làm thành viên xuất.

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

và trong 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

xuất không phải là thứ bạn xác định; nó được xử lý đặc biệt theo yêu cầu. Requirejs tạo một từ điển và chuyển nó qua bất kỳ định nghĩa nào yêu cầu 'xuất' để bạn có thể chia sẻ giá trị giữa xác định cuộc gọi. Bạn không cần phải tạo một tập tin và cũng không làm bất cứ điều gì đặc biệt - chỉ cần sử dụng tên ma thuật 'xuất khẩu' như là một trong những phụ thuộc của bạn. – dokkaebi

+0

Vui lòng cho tôi biết tôi nên khởi tạo mô-đun nào? cả hai hoặc chỉ một, và nếu chỉ một, mà giữa ModuleCollection và ModuleModel? –

+0

Sử dụng mã tôi đã đăng, cả ModuleModel và ModuleCollection sẽ hoạt động như mong đợi. Ở những nơi khác trong mã của bạn, bạn có thể làm một cái gì đó như 'require (['ModuleCollection', 'ModuleModel'], hàm (ModuleCollection, ModuleModel) {myModules = new ModuleCollection(); myModel = new ModuleModel ({/ * một số giá trị * /} myModules.add (myModel);} '. Nó có thể giúp bạn xem những gì bạn đang cố gắng làm - nếu điều này không hoạt động như mong đợi, bạn có thể mở một câu hỏi mới và liên kết đến nó ở đây. – dokkaebi

3

Tôi đã xem qua vấn đề này từ đây: RequireJS + BackboneRelational + Self-Referential. Dường như anh ta đã thừa hưởng một số vấn đề của anh ta từ chủ đề này vì vậy tôi nghĩ tôi có thể thêm xu của mình.

Đầu tiên, vì bạn đang sử dụng RequireJS, không có biến toàn cầu. Bạn không thể chỉ đơn giản là cung cấp tên của đối tượng, bạn cần cung cấp các tham chiếu đối tượng thực tế cho relatedModelcollectionType.

Vấn đề phức tạp nhất của bạn là ModuleModel 'relatedModel thực sự là ModuleModel, sẽ không được xác định khi bạn gán cho relatedModel (sử dụng mô hình AMD). Bạn phải hoãn chuyển nhượng cho đến sau khi được gán ModuleModel.

Cuối cùng, bạn cần giải quyết tham chiếu vòng tròn. dokkaebi đang đi đúng hướng khi anh ta đề xuất sử dụng exports, nhưng việc thực hiện của anh ấy thực sự lạm dụng exports.Khi xuất, đính kèm đối tượng trực tiếp vào exports như anh ta gợi ý, nhưng khi bạn nhập, bạn cần tham chiếu mô-đun để sử dụng nó, chứ không phải exports.

này nên làm việc:

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

Tôi đã gặp phải vấn đề tương tự khi trở lại và làm theo cách tiếp cận được Andrew Ferk sử dụng cho câu hỏi của mình: Backbone-relational submodels with RequireJS. Vấn đề nảy sinh bởi vì bạn đang định nghĩa các mô hình như là các mô-đun Yêu cầu để chúng không tồn tại trên phạm vi toàn cầu, nơi mà quan hệ xương sống có thể tìm kiếm chúng. Thay vì sử dụng phạm vi toàn cầu (đánh bại mục đích Yêu cầu) hoặc xuất (bit phức tạp với các mối quan hệ), bạn có thể xác định phạm vi cho các mô hình của mình và cho xương sống quan hệ để tìm các mô hình trong đó, với 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; 
} 

Bằng cách này, bạn nên sử dụng phụ thuộc Backbone và không cần phải jQuery và Underscore cho nó.

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

Kinda muộn cho điều này ngay bây giờ nhưng hy vọng nó sẽ giúp người khác.

Các vấn đề liên quan