1

バックボーンで単純なコレクションをレンダリングする際に問題が発生しています。レンダー イベントがリスナーから発生することはありません。どこが間違っているのかわかりません。誰か助けてください。

モデルを含むファイル:

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

私は何かを忘れていますか?

4

1 に答える 1

0

あなたが直面している問題は、バックボーン モデルとコレクションを最大限に活用していないことです。manual を呼び出している場合$.ajax(...)、Backbone イベントは発生しません。コードを Backbone と統合するためのいくつかの提案を次に示します。

まず、適切な予約済みキーワードを使用してビューをインスタンス化する必要があります。collection

var metricdevices = new MetricDevicesCollection();
$('#content').html(new MetricView({ collection : metricdevices }).render().el);

コレクション内のバックボーン イベントは、正確な REST API プラクティスで動作することを目的としています。aModelに属する aは、そのパラメーターCollectionを継承しurlます。REST API が次のスキームにマップされることを想定しています。

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 

アイデアは、モデルを個別に操作し、必要に応じてコレクションを使用して関連するすべてのモデルを取得できるということです。あなたの API は、そのようなワークフローに適応していないようです。データを最新の状態に保つモンキー パッチfetchは、操作が成功したときにコレクションのをトリガーすることです。

var collection = this.collection;
$.ajax({
  //...
  success: {
    collection.fetch();
  }
}

すでにバックボーン イベントをリッスンしているため、resetイベントがトリガーされ、ビューがレンダリングされます。これは良い方法ではないことに注意してください。アクセスできる場合は、サーバー アクセス ポイントをリファクタリングして、標準的な適切な REST プラクティスに準拠させる必要があります。そうでない場合は、適切なオブジェクト指向パターンを使用し、モデルにモデルの動作を実装してください。例えば:

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

そして、ビューからオブジェクトを適切に呼び出すことができます:

var ip = document.getElementById('vaddress').value;
var threshold = document.getElementById('vthreshold').value;
var metricDevice = new MetricDevice({ ip : ip, treshold : treshold });
this.collection.add(metricDevice.enable());
于 2013-07-09T23:40:50.380 に答える