我在主干中渲染一个简单的集合时遇到了问题,渲染事件永远不会从侦听器中触发......我不确定哪里出错,可以请别人帮帮我吗?
带模型的文件:
window.MetricDevice = Backbone.Model.extend({
defaults: {
ip: null,
framesReceived: null,
framesOutOfOrder: null,
framesLost: null
}
});
window.MetricDevicesCollection = Backbone.Collection.extend({
model: MetricDevice,
value: null,
url: function(){
return hackBase + "/wm/iptv/metric/devices/json";
},
initialize:function () {
this.fetch({ reset: true });
console.log("data fetched");
},
});
渲染页面:
window.MetricItemView = Backbone.View.extend({
events: {
"click input[type=button]" : "removeDevice",
},
initialize:function(){
this.template = _.template(tpl.get('metric-devices-item'));
this.render();
},
removeDevice:function(){
$.ajax({
url:hackBase + '/wm/iptv/metric/disable/' + this.model.get("ip") + '/0/json',
dataType:"json",
success:function (data) {
if ( data.return == 1 ){
alert(data.error);
}else{
alert("Metric disabled in " + this.model.get("ip"));
}
},
});
},
render:function(){
var ip = this.model.get("ip");
console.log("rendering item in view " + ip);
},
});
window.MetricView = Backbone.View.extend({
events: {
"click input[type=button]" : "add",
"click input[type=img]" : "updateAll",
},
clicked:function(e){
},
updateAll:function(e){
this.render();
},
initialize:function () {
this.template = _.template(tpl.get('metric-devices-list'));
this.model.bind("change", function(){
console.log("metricView data change detected");
this.render();
});
this.model.bind("reset", this.render());
},
add:function(e){
if($(e.currentTarget).attr("name") == "add" ){
var ip = document.getElementById('vaddress').value;
var threshold = document.getElementById('vthreshold').value;
$.ajax({
url:hackBase + '/wm/iptv/metric/enable/' + ip + '/' + threshold + '/json',
dataType:"json",
success:function (data) {
if ( data.return == 1 ){
alert(data.error);
}else{
alert("Metric enabled in device");
}
},
});
}else if($(e.currentTarget).attr("name") == "cancel"){
document.getElementById('vaddress').value = "";
document.getElementById('vthreshold').value = "";
}
},
render:function (eventName) {
$(this.el).html(this.template());
var list = $(this.el).find('#tableData');
console.log("On render!");
var subviews = [];
console.log("looping on models");
_.each(this.model.models, function (sw) {
console.log("model loop " + sw.get("ip"));
var m = new MetricItemView({model:sw, tagName: 'tbody', el: $(this.el).find('#tableData')});
list.append(m.template(sw.toJSON()));
}, this);
return this;
},
});
问题是MetricView中的render方法是在第一次加载页面时调用的,之后我认为JSON会保持缓存状态,如果我关闭浏览器就会改变内容缓存并再次运行...
控制台输出是:
On render! metricView.js:86
looping on models metricView.js:88
model loop 10.0.0.1 metricView.js:92
rendering item in view 10.0.0.1 metricView.js:26
我正在像这样实例化MetricView
var metricdevices = new MetricDevicesCollection();
$('#content').html(new MetricView({model:metricdevices}).render().el);
我忘记了什么吗?
答案 0 :(得分:0)
您面临的问题是您没有充分利用Backbone模型和集合。当您调用手动$.ajax(...)
时,不会触发Backbone事件。以下是一些建议,可以使您的代码与Backbone集成。
首先,您应该使用正确的保留关键字实例化您的视图:collection
var metricdevices = new MetricDevicesCollection();
$('#content').html(new MetricView({ collection : metricdevices }).render().el);
集合中的骨干事件旨在使用精确的REST API实践。属于Model
的{{1}}将继承其Collection
参数。它希望您的REST API映射到以下方案:
url
这个想法是你可以单独操作模型,并在需要时使用集合来获取所有相关模型。您的API似乎不适合此类工作流程。
保持数据更新的 monky patch 是在操作成功时触发集合的model.save() --> model.id is present ? PUT collection.url/model.id : POST collection.url
model.delete() --> DELETE collection.url/model.id
model.fetch() --> GET collection.url/model.id
。
fetch
由于您已经在监听Backbone事件,因此它将触发var collection = this.collection;
$.ajax({
//...
success: {
collection.fetch();
}
}
事件并呈现视图。请注意, 这是一种很好的做事方式。如果您有权访问它,您应该做的是重构您的服务器访问点以符合标准的良好REST实践。如果不这样做,请使用正确的面向对象模式并在模型中实现模型行为。例如:
reset
然后您可以从视图中正确调用该对象:
window.MetricDevice = Backbone.Model.extend({
defaults: {
ip: null,
framesReceived: null,
framesOutOfOrder: null,
framesLost: null
},
enable : function() {
var device = this,
ip = this.ip,
treshold = this.treshold;
$.ajax({
url:hackBase + '/wm/iptv/metric/enable/' + ip + '/' + threshold + '/json',
dataType:"json",
success:function (data) {
if ( data.return == 1 ){
alert(data.error);
} else {
device.trigger('change');
alert("Metric enabled in device");
}
}
});
return this;
}
});