我正在使用主干从一些平面数据中构建分层数据模型,并在尝试使用关系模型时遇到问题。以下代码的输出如下所示:
"D"
"B"
"C"
"F"
"G"
"A"
其中每个字母对应于相关模型中的一个 id。当我将关联添加到 TreeNode 模型中以形成关系时,树停止迭代,我只得到第一组结果 (D > B > C) 而不是 (D > B > F) 或 (D > G > A ) 如我所愿。这是我添加关系时的输出:
{"label":"Fred","language":"en","id":"D","datatype":"number"}
{"label":"is friends with","language":"en","id":"B","datatype":"text"}
{"label":"Violet","language":"en","id":"C","datatype":"text"}
我是骨干关系的新手,不确定我是否正确执行此操作。这是示例代码(我尽可能将其配对,并用 HERE IS THE PROBLEM 指出问题区域)
提前致谢!!!
<!DOCTYPE html>
<html>
<head>
<title>Relational Graph</title>
<meta charset="utf-8" />
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.1/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
<script src="js/backbone.marionette.js"></script>
<script src="js/backbone.relational.js"></script>
</head>
<body>
<div id="model"></div>
<script>
$(document).ready(function(){
MainApp = new Backbone.Marionette.Application();
MainApp.addRegions({treeRegion: "#model"});
MainApp.addInitializer(function(options){
var trunk = things.search({id: "D"}).first();
var tree = new TreeNodeCollection(graphify(options.relationships, trunk));
var treeView = new TreeRoot({collection: tree});
this.treeRegion.show(treeView);
});
TreeNode = Backbone.RelationalModel.extend({
initialize: function(){
var nodes = this.get("nodes");
if (nodes){
this.nodes = new TreeNodeCollection(nodes);
this.unset("nodes");
}
},
render: function(){
var that = this;
TemplateManager.get(this.template, function(template){
var html = $(template).tmpl();
that.$el.html(html);
});
return this;
}
// !!! HERE IS THE PROBLEM - when I add this line, it stops looping through the tree :(
//, relations: [{type: Backbone.HasOne, key: 'id', relatedModel: "Thing"}]
});
TreeNodeCollection = Backbone.Collection.extend({model: TreeNode});
TreeView = Backbone.Marionette.CompositeView.extend({
template: "#node-template",
tagName: "ul",
initialize: function(){
this.collection = this.model.nodes;
},
appendHtml: function(collectionView, itemView){
collectionView.$("li:first").append(itemView.el);
}
});
TreeRoot = Backbone.Marionette.CollectionView.extend({itemView: TreeView});
Thing = Backbone.RelationalModel.extend();
Things = Backbone.Collection.extend({
model: Thing,
search: function(opts){
return new Things(this.where(opts));
}
});
Relationship = Backbone.RelationalModel.extend({
relations: [
{type: Backbone.HasOne, key: 's', relatedModel: Thing},
{type: Backbone.HasOne, key: 'p', relatedModel: Thing},
{type: Backbone.HasOne, key: 'o', relatedModel: Thing}
]
});
Relationships = Backbone.Collection.extend({
model: Relationship,
search: function(opts){
return new Relationships(this.where(opts));
}
});
things = new Things([
new Thing({label: 'Sam', language: 'en', id: 'A', datatype: 'text'}),
new Thing({label: 'Fred', language: 'en', id: 'D', datatype: 'number'}),
new Thing({label: 'Jake', language: 'en', id: 'E', datatype: 'text'}),
new Thing({label: 'Sally', language: 'en', id: 'F', datatype: 'number'}),
new Thing({label: 'is friends with', language: 'en', id: 'B', datatype: 'text'}),
new Thing({label: 'is working with', language: 'en', id: 'G', datatype: 'text'}),
new Thing({label: 'Violet', language: 'en', id: 'C', datatype: 'text'})
]);
relationships = new Relationships([
new Relationship({s: "A", p: "B", o: "C"}),
new Relationship({s: "A", p: "B", o: "D"}),
new Relationship({s: "A", p: "B", o: "E"}),
new Relationship({s: "A", p: "B", o: "F"}),
new Relationship({s: "D", p: "B", o: "C"}),
new Relationship({s: "D", p: "B", o: "F"}),
new Relationship({s: "A", p: "G", o: "F"}),
new Relationship({s: "D", p: "G", o: "A"})
]);
MainApp.start({things: things, relationships: relationships});
function arrUnique(field, arr){
var all = [];
arr.each(function(item){
all.push(item.get(field).get('id'));
});
return _.uniq(all);
}
function graphify(arr, obj){
var graphNew = [];
var uniqueSubjects = arrUnique("s", arr.search({s: obj}));
for (var i=0; i<uniqueSubjects.length; i++){
var subject = uniqueSubjects[i];
var newSubject = {id: subject};
var subNodes = [];
var uniquePredicates = arrUnique("p", arr.search({s: obj}));
for (var j=0; j<uniquePredicates.length; j++){
var predicate = uniquePredicates[j];
var newPredicate = {id: predicate};
var relatedObjects = [];
arr.each(function(o){
if (o.get("s").get("id") == subject && o.get("p").get("id") == predicate){
relatedObjects.push({id: o.get("o").get("id")});
}
});
newPredicate.nodes = relatedObjects;
subNodes.push(newPredicate);
}
newSubject.nodes = subNodes;
graphNew.push(newSubject);
}
return graphNew;
}
});
</script>
<script type="text/template" id="node-template">
<li><label><%= JSON.stringify(id) %></label></li>
</script>
</body>
</html>