0

I would like a good answer here, not looking for any answers that are 'Have you tried X?', would rather have a knowledgeable source with a firm answer.

I have an observable array that I am using to fill in a chart. The observable array could contain up to 10k POJO's that are retrieved from Breeze.js in the local cache. When I first go out and get the data from the server, and then make a call against the local cache it is returned almost instantaneously.

On the next call, it gets exponentially slower. The objects being returned are not each observables nor do they contain observables, since I am performing a Breeze query with select they are POJO's. The problem is they continue to get slower and slower as I go back and continue to get the same data set. It is almost leading me to think somehow I am creating a memory leak in the observable array somehow.

In my view -

<h1>There are <span data-bind="text: chartData().length"></span> chart items</h1>

In my view model -

var chartData = ko.computed(function () {
    var myArray = ko.observableArray();
    var params = { xmin: xMin(), xmax: xMax() };
    if (!initialized) { return myArray(); }
    datacontext.getData(myArray, params.xmin, params.xmax false);
    return myArray();
}).extend({ throttle: 2000 });

In a datacontext.js file where the query is executing -

if (!forceRemote) {
    var thisData = manager.executeQueryLocally(query);
    myObservable([]);
    var myArray = myObservable();
    ko.utils.arrayPushAll(myArray, thisData);
    return myObservable.valueHasMutated();
}

I tried the arrayPushAll and value mutation based on a recommendation from another SO.com question but it doesn't appear to be any faster than setting myObservable([]) and then setting it equal to thisData.

Because of the large data set I would like to reduce this to as short of a recalculation as possible.

The reason I am setting the xmin and xmax as params is to make the computed dependent on the two observables...

4

2 回答 2

3

我自己发现 Knockout 在过滤时很慢,尤其是在 IE8 上。不幸的是,这对我来说仍然是受支持的浏览器 :-( 问题是我正在过滤一个带有复杂 html 模板的大型集合。IE8 渲染引擎很适合并不断抛出“运行缓慢的脚本”警报。

我通过使用 CSS 'display' 属性解决了这个问题。我为集合中的每个元素添加了一个可见的 Observable,以及以下数据绑定。(其中 hidden 是一个带有 display:none 的 css 类;)

data-bind="css:{'hidden':visible()===false}"

然后您所要做的就是遍历集合并根据需要设置属性。这对我的情况产生了巨大的影响。

于 2014-02-05T17:18:11.490 回答
2

简化您的计算 observable。很少有理由在计算的 observable 中创建 observable。

var chartData = ko.computed(function () {
    var min = xMin(), max = xMax(); // ensure we have a dependency
    return !initialized ? [] : datacontext.getData(min, max, false);
}).extend({ throttle: 2000 });

查询只需要返回数据:

if (!forceRemote) {
    var thisData = manager.executeQueryLocally(query);
    return thisData;
}

编辑:

假设您已经加载了所有数据并将其存储在一个数组中,您的计算 observable 可以ko.utils.arrayFilter用来计算过滤结果:

var chartData = ko.computed(function () {
    var min = xMin(), max = xMax(); // ensure we have a dependency
    return !initialized ? [] : ko.utils.arrayFilter(dataArray, function(item) {
        return item.x >= min && item.x <= max;
    });
});
于 2013-09-17T00:16:06.380 回答