【问题标题】:Knockout 2.3.0 IE Memory Leak淘汰赛 2.3.0 IE 内存泄漏
【发布时间】:2013-10-21 14:29:57
【问题描述】:

我遇到了一个问题,我在 IE 中使用 Knockout 2.3.0 遇到了内存泄漏。我有一个显示在屏幕上的结果列表,并且该结果集具有分页功能。有一个 AJAX 回调到控制器以获取下一组分页结果。最初将第一页绑定到屏幕时,IE 的内存负载约为 150Mb,但每个页面增加了约 50Mb 到 100Mb,Chrome 或 FireFox 不会出现此问题。

这个问题似乎很常见,我看过很多例子,例如: KnockoutJS Memory Leak 我试图复制这个模型无济于事,这是我的 KO 脚本文件的样子:

var householdViewModel = ko.observable();

var HouseholdViewModel = function (data) {
    ko.mapping.fromJS(data, mapping, this);    
};

var AccountViewModel = function (data) {
    ko.mapping.fromJS(data, mapping, this);
};

var mapping = {
    'Households': {
        create: function(options) {
            return new HouseholdViewModel(options.data);
        }
    },
    'Accounts': {
        create: function (options) {
            return new AccountViewModel(options.data);
        }
    }
};

我正在使用 MVC 框架进行 AJAX 调用,如下所示:

@Ajax.ActionLink(">", "PageInfo", new {pageOption = "Next"}, new AjaxOptions {UpdateTargetId = "SearchResults", HttpMethod = "GET", OnBegin = "OnBeginAjaxListManipulation", OnComplete = "OnCompleteAjaxListManipulation"}, new {@class = "textNavigationElement"})

使用如下所示的回调 JS 方法:

    function OnCompleteAjaxListManipulation() {
        //ko.cleanNode(document.getElementById("SearchResults"));
        var HHVM = { Households: ko.mapping.fromJS(@Html.Raw(Json.Encode(Model.Households))) };
        householdViewModel(new HouseholdViewModel(HHVM));
        //ko.applyBindings(householdViewModel, document.getElementById("SearchResults"));
    }

我想我需要说明我有一个名为 Info.cshtml 的页面和一个名为 results.cshtml 的部分页面,它将显示搜索结果。在信息页面中,我进行了以下调用;

    var HHVM = { Households: ko.mapping.fromJS(@Html.Raw(Json.Encode(Model.Households))) };
    householdViewModel(new HouseholdViewModel(HHVM));
    ko.applyBindings(householdViewModel, document.getElementById("SearchResults"));

搜索结果会在第一页正常显示,但第二页没有显示。如果我在 JS 回调中添加第二个 applyBindings,它可以工作,但我会遇到内存泄漏问题。我无法弄清楚这一点,任何帮助将不胜感激。

乔什

【问题讨论】:

    标签: asp.net-mvc-4 knockout.js knockout-2.0 knockout-mapping-plugin


    【解决方案1】:

    我通过手动控制可观察数组来修复它,这可能是您应该这样做的方式。首先,我将模型更改为:

    var Households = ko.observableArray(HouseholdViewModel);
    
    var HouseholdViewModel = function (data) {
        ko.mapping.fromJS(data, mapping, this);    
    };
    
    var AccountViewModel = function (data) {
        ko.mapping.fromJS(data, mapping, this);
    };
    
    var mapping = {
        'Households': {
            create: function(options) {
                return new HouseholdViewModel(options.data);
            }
        },
        'Accounts': {
            create: function (options) {
                return new AccountViewModel(options.data);
            }
        }
    };
    

    然后更改了触发Ajax的方式,我删除了UpdateTargetId并决定自己控制它,代码如下所示:

    @Ajax.ActionLink(">>", "PageInfo", new {pageOption = "Last"}, new AjaxOptions {HttpMethod = "GET", OnBegin = "OnBeginAjaxListManipulation", OnComplete = "OnCompleteAjaxListManipulation", OnSuccess = "BindModel"}, new {@class = "textNavigationElement"}) 
    

        function BindModel(e) {
            var isBound = !!ko.dataFor(document.getElementById("SearchResults"));
            if (isBound)
                Households.removeAll();
    
            $.each(e.Households, function (index, value) {
                var hh = new HouseholdViewModel(value);
                Households.push(hh);
            });
    
            if (!isBound)
                ko.applyBindings(Households, document.getElementById("SearchResults"));
        }
    

    就是这样!结果是,每次绑定模型时,它都会清除可观察数组并读取项目,因为将可观察数组绑定到页面,我们不需要做任何 ko.CleanNode 和重新绑定 :-)

    我希望这可以帮助其他人。

    【讨论】:

      猜你喜欢
      • 2015-02-13
      • 1970-01-01
      • 1970-01-01
      • 2017-12-11
      • 2013-04-10
      • 1970-01-01
      • 2013-02-04
      • 2012-02-18
      • 2013-04-28
      相关资源
      最近更新 更多