【问题标题】:Backbonejs add to collection only if fetch data different仅当获取数据不同时,Backbonejs 才会添加到集合中
【发布时间】:2013-10-04 22:43:53
【问题描述】:

我正在编写一个小应用程序,它调用一个 json 请求,其中包含有关正在为音乐播放器播放的曲目的数据。每 2-3 分钟跟踪 json 请求更改。如果先前调用的条目不同,我试图让骨干只触发并将另一个模型添加到我的集合中。到目前为止,这是我的代码,但是它一直在渲染相同的数据

// Model: Track
//
//  
window.Track = Backbone.Model.extend({});   


// Collection: Tracks
//
//  
window.Tracks = Backbone.Collection.extend({ 
    model: Track,
    url: "api/nowplaying/1.json",
    parse: function (response) {
        return response.response.body;
    }
});


// View: MetaDataView 
//
//  
window.MetaDataView = Backbone.View.extend({
    template: "#metadata-template",
    tagName: 'li',
    className: 'metadata',

    initialize: function() {
        _.bindAll(this, 'render');
        this.model.bind('change', this.render);
        this.initializeTemplate();
    },

    initializeTemplate: function() {
        this.template = _.template($(this.template).html());
    },

    render: function() { 
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    }
});


// View: MetaDataLibraryView
//
//
window.MetaDataLibraryView = Backbone.View.extend({
    tagName: 'section', 
    className: 'metadata-library', 

    initialize: function() {
        _.bindAll(this, 'render', 'startup', 'renderNew');
        this.template = _.template($('#metadata-library-template').html());
        //this.collection.bind('reset', this.render);
        this.collection.on('add', this.renderNew, this);
        this.startup();
    },
    startup: function() {
        var e = this;
        window.setInterval(function () {
            console.log('fetching');
            e.collection.fetch({update: true, remove:false, add: true});
        }, 2000); 
    },
    renderNew: function(newModel) {
        var collection = this.collection;
        $metadata = this.$(".metadata-library");
        var view = new MetaDataView({ model: newModel, collection: collection });
        $metadata.append(view.render().el);
        return this;

    },
    render: function() {
        var $metadata,
            collection = this.collection;

        $(this.el).html(this.template({}));
        $metadata = this.$(".metadata-library");
        this.collection.each(function(schedule) {
            var view = new MetaDataView({ model: schedule, 
                                           collection: collection });
            $metadata.append(view.render().el);
        });

        return this;
    }
});

我在 stackoverflow 上发现了有关使用集合获取选项的可能性的帖子,例如 {update: true, remove:false, add: true}。仅当正在获取的模型发生更改时,我将如何获取要呈现的数据?

【问题讨论】:

  • “如果之前调用的条目不同”是什么意思?我没有看到你在任何地方取模型。只有一个集合:e.collection.fetch({...})。你能详细说明一下吗?
  • 也许我很困惑。我指的是我获取的每个集合只有一个模型。如果该模型不同,则需要将其添加到集合中并渲染它,但不重新渲染视图中已渲染的其余模型
  • 假设您的集合中有一个模型,您进行提取,这会产生不同的模型,然后将其添加到您的模型中。当您进行另一次 fetch 并且您的收藏中有 2 个模型时会发生什么?您想将它与集合中的两个模型进行比较,还是仅将其与最近添加的模型进行比较?
  • 我想将它与最近添加的一个进行比较。这是因为曲目可能会在以后再次播放并且已经在该集合中。我仍然需要添加它。

标签: json backbone.js backbone-views backbone-events


【解决方案1】:

这样的东西应该可以工作

startup: function() {
    window.setInterval(function () {
        console.log('fetching');
        var track = new Track();
        track.fetch()
        .done(function() {
            if(!this.isSamePrevTrack(track)) {
                e.collection.add(track);
            }
        }.bind(this));
    }.bind(this), 2000); 
},

isSamePrevTrack: function(track) {
    if(!this.prevTrack) {
      this.prevTrack = track;
      return false;
     }
    // Do some test to see if the track is the same
    // ie. return this.prevTrack.get('id') === track.get('id');
});

【讨论】:

  • 我稍后会尝试这个,但我知道这将如何解决我的问题。另一个问题:调用创建新Track()时。如果模型数据没有不同,销毁对象是否明智?或者有一个孤立的对象会消失而不占用内存?
  • 如果 isSamePrevTrack 返回 true 并且您没有将其添加到您的集合中,则变量 track 应该在它超出范围后的某个时间被垃圾收集。所以不,我认为您不需要做任何额外的事情来确保运行时释放为轨道分配的内存。
猜你喜欢
  • 1970-01-01
  • 2021-12-03
  • 2015-05-04
  • 1970-01-01
  • 1970-01-01
  • 2019-07-19
  • 2021-02-18
  • 2017-04-21
  • 1970-01-01
相关资源
最近更新 更多