设置
我是新的骨干,并使用它与Backgrid显示大量的数据。数据表示两个成分列表:一个具有现有的值,另一个具有更新的值。数据库中没有此数据的主键,因此我们的目标是能够按名称手动匹配新旧成分,然后从匹配的数据生成DB更新。为此,我有三个集合:ingredientsOld
(数据库)、ingredientsNew
(update.xml)和ingredients
。ingredientsOld
和ingredientsNew
集合只是基本Ingredient
模型的集合。然而,ingredients
集合是IngredientComp
模型的集合,其中包含一个整数状态,一个"旧"Ingredient
和一个"新"Ingredient
。
var Ingredient = Backbone.Model.extend({});
var Ingredients = Backbone.Collection.extend({ model: Ingredient });
var IngredientComp = Backbone.Model.extend({
constructor: function(attributes, options) {
Backbone.Model.apply( this, arguments );
if (attributes.o instanceof Ingredient) {
this.o = attributes.o;
console.log("Adding existing ingredient: "+this.o.cid);
} else {
this.o = new Ingredient(attributes.o);
console.log("Adding new ingredient: "+this.o.get("name"));
}
if (attributes.n instanceof Ingredient) {
this.n = attributes.n;
} else {
this.n = new Ingredient(attributes.n);
}
}
});
var IngredientComps = Backbone.Collection.extend({
model: IngredientComp,
comparator: function(comp){
return -comp.get("status");
}
});
var ingredientsOld = new Ingredients();
var ingredientsNew = new Ingredients();
var ingredients = new IngredientComps();
数据由PHP生成并输出到JSON,如下所示:
ingredientsOld.add([
{"name":"Milk, whole, 3.25%","guid":"3BDA78C1-69C1-4582-83F8-5A9D00E58B45","item_id":16554,"age":"old","cals":"37","fat_cals":"18","protein":"2","carbs":"3","fiber":"0","sugar":"3","fat":"2","sat_fat":"1","trans_fat":"0","chol":"6","sod":"24","weight":"2.00","quantity":"1 each","parents":{"CC09EB05-4827-416E-995A-EBD62F0D0B4A":"Baileys Irish Cream Shake"}}, ...
ingredients.add([
{"status":3,"o":{"name":"Sliced Frozen Strawberries","guid":"A063D161-A876-4036-ADB0-C5C35BD9E5D5","item_id":16538,"age":"old","cals":"77","fat_cals":"0","protein":"1","carbs":"19","fiber":"1","sugar":"19","fat":"0","sat_fat":"0","trans_fat":"0","chol":"0","sod":"0","weight":"69.60","quantity":"1 each","parents":{"BC262BEE-CED5-4AB3-A207-D1A04E5BF5C7":"Lemonade"}},"n":{"name":"Frozen Strawberries","guid":"5090A352-74B4-42DB-8206-3FD7A7CF9D56","item_id":"","age":"new","cals":"77","fat_cals":"0","protein":"1","carbs":"19","fiber":"1","sugar":"19","fat":"0","sat_fat":"0","trans_fat":"0","chol":"0","sod":"0","weight":"","quantity":"69.60 Gram","parents":{"237D1B3D-7871-4C05-A788-38C0AAC04A71":"Malt, Strawberry"}}}, ...
当我显示来自成分模型的值(来自自定义Backgrid Cell的渲染函数)时,我最初必须像这样输出它们:
render: function() {
col = this.column.get("name");
var v1 = this.model.get("o")[col];
var v2 = this.model.get("n")[col];
this.$el.html( v1 + "n<br />n<b>" + v2 + "</b>" );
return this;
}
<标题>只有在将成分模型从一个集合移动到另一个集合之后,this.model.get("o").get(col);
函数才能工作。下面是将components从一个集合移动到另一个集合的函数:
function matchItems(oldId, newId) {
var oldItem = ingredientsOld.remove(oldId);
var newItem = ingredientsNew.remove(newId);
ingredients.add({'status': 1, 'o': oldItem, 'n': newItem});
}
我已经更新了渲染函数,以尝试检索值的两种方法,但它有点慢,当然不是处理问题的正确方式:
render: function() {
col = this.column.get("name");
// Investigate why the Ingredient model's get() method isn't available initially
var v1 = this.model.get("o")[col];
// The above line returns 'undefined' if the Ingredient model has moved from one
// collection to another, so we have to do this:
if (typeof v1 === "undefined"){ v1 = this.model.get("o").get(col)};
var v2 = this.model.get("n")[col];
if (typeof v2 === "undefined"){ v2 = this.model.get("n").get(col)};
this.$el.html( v1 + "n<br />n<b>" + v2 + "</b>" );
return this;
}
谁能告诉我是什么导致了这个问题?我已经对backbone - relationship .js做了一些研究,但是对于我想要完成的任务来说,它似乎太多了。
标题>我首先建议使用initialize
而不是constructor
,因为构造函数覆盖并延迟了模型的创建。
主要问题是model.get('o')在这个if语句中返回一些不同的东西。通过执行this.o
,它不是在模型上设置属性,而是在模型对象上设置属性。因此,当实际创建模型时,model.get('o')
是一个常规对象,而不是骨干模型。
if (attributes.o instanceof Ingredient) {
this.o = attributes.o;
console.log("Adding existing ingredient: "+this.o.cid);
} else {
this.o = new Ingredient(attributes.o);
console.log("Adding new ingredient: "+this.o.get("name"));
}
将if语句更改为以下语句应该可以解决问题。
if (attributes.o instanceof Ingredient) {
this.o = attributes.o;
console.log("Adding existing ingredient: "+this.o.cid);
} else {
this.set('0', new Ingredient(attributes.o));
console.log("Adding new ingredient: "+this.o.get("name"));
}