自动更新主干集合

时间:2013-07-09 15:47:52

标签: backbone.js collections render

我在主干中渲染一个简单的集合时遇到了问题,渲染事件永远不会从侦听器中触发......我不确定哪里出错,可以请别人帮帮我吗?

带模型的文件:

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

我忘记了什么吗?

1 个答案:

答案 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;
    }
});