Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 筛选主干集合时内存泄漏_Javascript_Backbone.js_Backbone Events - Fatal编程技术网

Javascript 筛选主干集合时内存泄漏

Javascript 筛选主干集合时内存泄漏,javascript,backbone.js,backbone-events,Javascript,Backbone.js,Backbone Events,我有一个过滤器在我的主干收集上工作。在“搜索”框中键入搜索并列出live筛选器。很好,至少我是这么想的。当我在chrome中查看内存堆快照时,我可以看到每次搜索都会出现内存泄漏。。。6兆欧8兆欧。。。不久,堆快照就达到100多兆 我已经在下面的视图中隔离了这个问题。如果我在初始化函数中注释掉this.listenTo,我似乎不再泄漏内存 因此,我的问题是如何在不泄漏的情况下保持这些事件侦听器和集合上的实时过滤 var View = Backbone.View.extend({ tagN

我有一个过滤器在我的主干收集上工作。在“搜索”框中键入搜索并列出live筛选器。很好,至少我是这么想的。当我在chrome中查看内存堆快照时,我可以看到每次搜索都会出现内存泄漏。。。6兆欧8兆欧。。。不久,堆快照就达到100多兆

我已经在下面的视图中隔离了这个问题。如果我在初始化函数中注释掉this.listenTo,我似乎不再泄漏内存

因此,我的问题是如何在不泄漏的情况下保持这些事件侦听器和集合上的实时过滤

var View = Backbone.View.extend({

    tagName: 'tr',

    initialize: function() {
        this.listenTo(this.model, 'change', this.render);
        this.listenTo(this.model, 'destroy', this.remove);
    },

    events: {
        'click .edit': 'edit',
        'click .delete': 'delete',
    },

    edit: function() { /* EDIT */ },

    delete: function() {
        this.model.destroy(); //backbone
    },

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

})


var ListView = Backbone.View.extend({

    initialize: function()
    {
        this.collection = new Collection( Products ) //products are bootstrapped on load
    },

    render: function (terms)
    {
        this.$el.html( ListTemplate );

        var filtered = Shop.products.collection.search(terms)

        _.each(filtered, this.addOne, this)

        //append list to table
        $('#products').html( this.el )

        return this
    },

    addOne: function (product)
    {
        this.$el.find('tbody').append(
            new View({ model: product }).render().el
        )

        return this
    },

});

var Collection = Backbone.Collection.extend({

    model: Model,

    search : function(letters){

        //set up a RegEx pattern
        var pattern = new RegExp(letters,"gi")

        //filter the collection
        return this.filter(function(model)
        {
            if(letters == "") return true //if search string is empty return true
            return pattern.test(model.attributes['Product']['name'])
        });
    }


});
已解决:

这是我的新搜索方法。我不再过滤集合并重新渲染。我只是在集合上循环,如果模型与搜索匹配,我们将触发“显示”事件,如果不在搜索中,我们将触发“隐藏”事件。然后我们在视图中订阅这些事件并相应地采取行动

集合中的搜索功能: 搜索:功能(查询){

新观点: var ProductView=Backbone.View.extend({


要扩展@mu已经评论过的内容,您没有删除您创建的视图。它们不在DOM中,但它们仍然挂在内存中,因为它们引用了您的模型(因此,垃圾收集器不会为您删除它们)

您有两个选择:

  • 跟踪由
    addOne
    实例化的所有视图,并在每次调用
    render
    时将其删除
  • 使您的代码在每次更改筛选条件时显示/隐藏视图,而不是实例化/销毁。这需要更多的工作,但肯定是更好的解决方案

  • 所以你创建了很多
    视图
    实例,但从未对它们调用
    删除
    ?所以我知道我的问题是,我创建了无数个视图,也从未关闭它们。我只是想找到一个跟踪视图的好方法,这样我就可以关闭它们。或者正如@anshr在下面建议的那样,根据查询简单地隐藏/显示它们。这样的一个例子就是我到目前为止,我还没有找到thod。谢谢。我已经根据您的回答更新了我的问题的解决方案。
        //set up a RegEx pattern
        var pattern = new RegExp(query,"gi")
    
        //filter the collection
        this.each(function(model){
          if ( pattern.test(model.attributes['Product']['name']) ){
            model.trigger('show')
          }
          else{
            model.trigger('hide')
          }
    });
    }
    
        tagName: 'tr',
    
        initialize: function() {
            this.listenTo(this.model, 'show', this.show);
            this.listenTo(this.model, 'hide', this.hide);
        },
    
        hide: function()
        {
          this.$el.addClass('hide')
        },
    
        show: function()
        {
          this.$el.removeClass('hide')
        },
    
        render: function ()
        {
            var template = _.template( ProductTemplate )
            this.$el.html( template( {data: this.model.toJSON(), Utils: Shop.utils} ) )
            return this;
        }
    
    });