好的。我打算在这里放弃并寻求帮助。我想我遇到了多个问题而且不确定最好的方法。我正在使用把手创建一个我的json对象的骨架模型。现在模板工作我想点击获取模型,以便能够添加到另一个集合。
我的第一个问题。我认为骨干默认定义了一个模型ID?如果我将默认设置为“”或null,则每个模型的id为“”或null。 json对象有一个我可以分配给主干id的id,但是如果我在默认的id:jsonID中这样做,则jsonID是未定义的。如果我在控制台中执行object.toJSON(),则没有创建主干的id。所以我没有在把手模板中使用的值来将我的div id分配给该模型的骨干ID。然后使用它来获取元素id,以便在单击时我可以获得骨干ID。或者至少我已经阅读了很多以这种方式做到的例子。
我的第二个问题,我认为源于requirejs。我看到的所有单击的例子甚至使用this.collection或this.model。在我的View文件中,那些总是返回undefined,假设这是因为requirejs。我特别尝试了这个例子http://lostechies.com/derickbailey/2011/10/11/backbone-js-getting-the-model-for-a-clicked-element/。我想知道我是否应该使用requirejs废弃,它似乎会导致更多问题然后帮助。
到目前为止,这是我的代码,我删除了我的点击功能代码,因为它没有工作。
收集档案:
define(['jquery', 'backbone', 'lodash', 'Models/GroceryItem'],
function($, Backbone, _, GroceryItem) {
var GroceryItems = Backbone.Collection.extend({
model: GroceryItem,
url: "data.json",
parse: function(response) {
return response.all_coupons;
}
});
var storeItems = new GroceryItems();
storeItems.fetch({
success:function(){
console.log(storeItems.toJSON());
}
});
return storeItems;
});
查看文件:
define(['jquery', 'backbone', 'lodash', 'handlebars', 'Collections/GroceryItems'],
function($, Backbone, _, Handlebars, storeItems) {
var GroceryItemsView = Backbone.View.extend({
template: Handlebars.compile(
'<ul class="d-row">' +
'{{#each storeItems}}' +
'<li class="lineItem" id="{{coupon_id}}">' +
'<div class="wrapper">' +
'<div class="header">{{coupon_title}}</div>' +
'<div class="column_wrapper">' +
'<div class="two-col">' +
'<div class="product_image"><img src="{{coupon_thumb}}" alt="{{coupon_description}}" height="110" width="110"></div>' +
'<div class="description">{{coupon_description}}</div>' +
'</div>' +
'</div>' +
'<div class="expiration">Valid From: {{valid_from}} to {{valid_to}}</div>' +
'</div>' +
'</li>' +
'{{/each}}' +
'</ul>'
),
events: {
"click li": "getModel"
},
getModel:function(e){
},
render: function() {
var that = this;
storeItems.fetch({
success: function(storeItems) {
var storeTemplate = that.template({storeItems: storeItems.toJSON()});
that.$el.html(storeTemplate);
return that;
}
})
return this;
}
});
return GroceryItemsView;
});
非常感谢帮助。非常感谢。如果我完全错了,我会接受任何建议。我只是在学习骨干和javascript,所以当我用大量的谷歌搜索时,我正在磨砺。
谢谢!
编辑代码:
define(['jquery', 'backbone', 'lodash', 'Collections/GroceryItems', 'Views/GroceryItemView'],
function($, Backbone, _, storeItems, GroceryItemView) {
var GroceryItemsView = Backbone.View.extend({
tagName: 'ul',
className: 'd-row',
el: '#container',
initialize: function () {
//basically says only render when collection syncs
this.listenTo(storeItems, 'sync', this.render);
},
render: function () {
//got keep track of views for when you need close them (not important for now but you'll thank me later)
this.groceryItemsView = [];
storeItems.each(function (GroceryItem) {
//we are making a new view for each model and passing it in as an option
var itemView = new GroceryItemView({
model: GroceryItem
});
//The view creates an element but it is not attached to DOM. We will attach it to the ItemsView's $el (which IS attached to the DOM)
this.$el.append(itemView.$el);
this.groceryItemsView.push(itemView);
}, this);
}
});
var list = new GroceryItemsView();
return list;
});
define(['jquery', 'backbone', 'lodash', 'handlebars', 'Views/GroceryItemsView', 'Models/GroceryItem'],
function($, Backbone, _, Handlebars, GroceryItemsView, GroceryItem) {
var GroceryItemView = Backbone.View.extend({
template: Handlebars.compile(
'<div class="wrapper">' +
'<div class="header">{{coupon_title}}</div>' +
'<div class="column_wrapper">' +
'<div class="two-col">' +
'<div class="product_image"><img src="{{coupon_thumb}}" alt="{{coupon_description}}" height="110" width="110"></div>' +
'<div class="description">{{coupon_description}}</div>' +
'</div>' +
'</div>' +
'<div class="expiration">Valid From: {{valid_from}} to {{valid_to}}</div>' +
'</div>'
),
tagName: 'li',
className: 'lineItem',
events: {
'click': 'getModel'
},
initialize: function () {
this.render();
},
getModel: function () {
return this.model;
},
render: function () {
this.$el.html(this.template(this.model.toJSON()));
}
});
return GroceryItemView;
});
答案 0 :(得分:1)
在骨干模型中实际上有两种id,第一种是id,它用于表示模型在服务器上的id,并且不是原子分配的。第二个是cid(客户端ID),主干将以原子方式生成并为您分配。
如果您的服务器模型的id属性未命名为id,则可以通过设置idAttributemodel属性来映射它。例如,如果json模型中的id被称为 jsonID
var GroceryItems = Backbone.Collection.extend({
model: GroceryItem,
idAttributemodel: jsonID,
url: "data.json",
parse: function(response) {
return response.all_coupons;
}
});
的更多信息
我在你的GroceryItems集合文件中看到你是声明你的集合并实例化它,在这种情况下更有意义的是声明它并返回你的应用程序视图(或任何地方)你声明你的集合视图)在那里实例化它并将它传递给视图。
为了在li
的点击事件中检索模型ID,您必须选择每个li
的单独视图,该视图绑定到特定模型,或者在您的如果您使用相同的视图渲染所有模型,则可以从DOM中检索它。
例如
getModel: function (e) {
//you might want to consider using data attributes instead
var modelId = $(e.currentTarget).attr('id');
var model = this.storeItems.get(modelId);
},
一般来说,关于使用require.js,我认为虽然从长远来看有一点学习曲线但值得。您可能要考虑做的一件事是为每个视图/模型/集合保留一个文件。
答案 1 :(得分:0)
获取所点击内容模型的最简单方法非常简单。
success
选项。只收听sync
事件。使代码更清晰,防止以后出现奇怪问题。 我还没有测试过这段代码,但逻辑有效(多次完成)
//Preferrably keep this in a separate file or use require-handlebars
var itemTpl = Handlebars.compile(
'<div class="wrapper">' +
'<div class="header">{{coupon_title}}</div>' +
'<div class="column_wrapper">' +
'<div class="two-col">' +
'<div class="product_image"><img src="{{coupon_thumb}}" alt="{{coupon_description}}" height="110" width="110"></div>' +
'<div class="description">{{coupon_description}}</div>' +
'</div>' +
'</div>' +
'<div class="expiration">Valid From: {{valid_from}} to {{valid_to}}</div>' +
'</div>');
//Your Collection
var GroceryItems = Backbone.Collection.extend({
model: GroceryItem,
url: "data.json",
parse: function (response) {
return response.all_coupons;
}
});
//This Represents all your views
var ItemsView = Backbone.View.extend({
tagName: 'ul',
el: '.where-this-is-supposed-to-go',
initialize: function () {
this.collection = new GroceryItems();
//basically says only render when collection syncs
this.listenTo(this.collection, 'sync', this.render);
},
render: function () {
//got keep track of views for when you need close them (not important for now but you'll thank me later)
this.itemViews = [];
this.collection.each(function (m) {
//we are making a new view for each model and passing it in as an option
var itemView = new ItemView({
model: m
});
//The view creates an element but it is not attached to DOM. We will attach it to the ItemsView's $el (which IS attached to the DOM)
this.$el.append(itemView.$el);
this.itemViews.push(itemView);
}, this);
}
});
var ItemView = Backbone.View.extend({
template: itemTpl,
tagName: 'li',
className: 'lineItem',
events: {
'click': 'getModel'
},
initialize: function () {
this.render();
},
getModel: function () {
//it's already there. No IDs
return this.model;
},
render: function () {
this.$el.html(this.template(this.model.toJSON()));
}
});