Jquery一次循环和绑定10条记录 [英] Jquery looping and binding 10 records at a time

查看:56
本文介绍了Jquery一次循环和绑定10条记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个场景,我从服务器获得数千条记录作为JSON并将所有记录绑定到页面。对于每条记录,我在jquery中进行一些计算并将数据绑定到UI。由于记录计数为1000,因此计算和绑定数据的时间更长。完成所有记录计算后,页面上的数据将被绑定。是否有任何选项可以逐个或10乘10绑定数据,并在UI上显示该集合的绑定。我想要找到的是一次为10条记录执行$ .each并将下一组10条记录附加到它上面,依此类推。任何想让页面加载更快的想法? (我的要求不需要分页)。任何线索都可以提供帮助。

I have a scenario where I get thousands of records from the server as JSON and bind all records to the page. For each record, I am doing some calculations in jquery and binding data to UI. As record count is in 1000's the time take for calculation and binding data is more. Data on the page is bound at the end when all records calculations are done. Is there any option to bind data one by one or 10 by 10 and show binding on UI for that set. What I am trying to find is to execute $.each for 10 records at a time and append next set of 10 records to it and so on. any idea to make the page load faster? (Paging is not required for my requirement). Any clue can help.

<div id="keepFinalDataHere"></div>


$.each(data, function (i, record) {

 content += "<div>" + record.id + "</div><div>" + record.fromId + "</div><div>" + record.subject + "</div>";
        });

    $(content).appendTo('#keepFinalDataHere');

在上面的代码中,内容是通过获取数千条记录构建的,一旦内容构建完成,它受到了div的约束。我正在寻找一个选项来获取前10个项目绑定数据,以确保用户感觉页面已加载,然后APPEND剩余项目100个左右的现有列表。

In above code, content is built by getting several thousands of records and once the content is built, then it is being bound to the div. I am looking for an option to get first 10 items bind the data to make sure that users feel like the page is loaded, and then APPEND remaining items in sets of 100 or so to existing list.

推荐答案

如果你想让UI保持响应并希望能够在渲染大量DOM元素之间执行代码,你将不得不使用超时机制。您可以将渲染方法传递给 的setTimeout

If you want to keep the UI responsive and want to be able to execute code in between rendering a large amount of DOM elements, you'll have to use a timeout mechanism. You can do so by passing your render method to setTimeout.

不是将方法添加到堆栈并立即执行, setTimeout 将方法推送到任务队列,只有当前的js堆栈清除后才执行它。

Instead of adding the method to the stack and executing it immediately, setTimeout pushes the method to a task queue and only executes it once the current js stack has cleared.

我建议的方法的主要步骤:

The main steps of the method I propose:


  1. 将您的数据集复制到临时数组

  2. 使用 splice 删除第一个 n 数组中的项目

  3. 将第一个 n 项呈现给DOM

  4. 如果还有剩余项目,请转到(2)

  1. Copy your data set to a temporary array
  2. Use splice to remove the first n items from the array
  3. Render the first n items to the DOM
  4. if there are still items left, go to (2)

这是代码的主要部分,带有注释,假设:

Here's the main part of the code, with comments, assuming:


  • testData 包含一系列数据点

  • createRow 保存将数据点转换为渲染DOM元素的逻辑

  • INITIAL_CHUNK_SIZE 保存您想要呈现的行数而不会超时。

  • DEFAULT_CHUNK_SIZE ho lds每个后续循环必须呈现的行数

  • testData holds an array of data points
  • createRow holds the logic to transform a data point to a rendered DOM element
  • INITIAL_CHUNK_SIZE holds the number of rows you want to render without a timeout.
  • DEFAULT_CHUNK_SIZE holds the number of rows each following loop has to render

超时渲染器 toRenderer ):

var toRenderer = function(s) {
  // We need a copy because `splice` mutates an array
  var dataBuffer = [].concat(testData);

  var nextRender = function(s) {
    // Default value that can be overridden
    var chunkSize = s || DEFAULT_CHUNK_SIZE; 

    dataBuffer
      .splice(0, chunkSize)
      .forEach(createRow);

    if (dataBuffer.length) {
      setTimeout(nextRender);
    }
  };

  // Triggers the initial (not timed out) render
  nextRender(INITIAL_CHUNK_SIZE);
};

在下面的示例中,我包含了一个移动微调器来显示渲染循环如何能够容纳一个不错的帧速率。

In the example below I've included a moving spinner to show how the render loop is able to hold a decent frame rate.

请注意, DEFAULT_CHUNK_SIZE 越大,您渲染所有项目的速度就越快。权衡:一旦一个渲染块超过1/60秒,你将失去平滑的帧速率。

Note that the larger the DEFAULT_CHUNK_SIZE, the faster you'll have all your items rendered. The tradeoff: once one render chunk takes more than 1/60s, you'll loose your smooth frame rate.

// SETTINGS
var DATA_LENGTH = 10000;
var DEFAULT_CHUNK_SIZE = 100;
var INITIAL_CHUNK_SIZE = 10;

var list = document.querySelector("ul");
var createRow = function(data) {
  var div = document.createElement("div");
  div.innerHTML = data;
  list.appendChild(div);
};

// Blocking until all rows are rendered
var bruteRenderer = function() {
  console.time("Brute renderer total time:");
  testData.forEach(createRow);
  console.timeEnd("Brute renderer total time:");
}

// Pushes "render assignments" to the "task que"
var toRenderer = function(s) {
  console.time("Timeout renderer total time:");
  var dataBuffer = [].concat(testData);

  var nextRender = function(s) {
    var chunkSize = s || DEFAULT_CHUNK_SIZE;

    dataBuffer
      .splice(0, chunkSize)
      .forEach(createRow);

    if (dataBuffer.length) {
      setTimeout(nextRender);
    } else {
      console.timeEnd("Timeout renderer total time:");
    }
  };

  nextRender(INITIAL_CHUNK_SIZE);
};

// EXAMPLE DATA, EVENT LISTENERS:


// Generate test data
var testData = (function() {
  var result = [];
  for (var i = 0; i < DATA_LENGTH; i += 1) {
    result.push("Item " + i);
  }
  return result;
}());

var clearList = function() {
  list.innerHTML = "";
};

// Attach buttons
document.querySelector(".js-brute").addEventListener("click", bruteRenderer);
document.querySelector(".js-to").addEventListener("click", toRenderer);
document.querySelector(".js-clear").addEventListener("click", clearList);

button {
  display: inline-block;
  margin-right: .5rem;
}
.spinner {
  background: red;
  border-radius: 50%;
  width: 20px;
  height: 20px;
  animation-duration: 1s;
  animation-timing-function: linear;
  animation-direction: alternate;
  animation-name: move;
  animation-iteration-count: infinite;
}
@keyframes move {
  from {
    transform: translate3d(800%, 0, 0);
  }
  to {
    transform: translate3d(0, 0, 0);
  }
}
ul {
  height: 200px;
  overflow-y: scroll;
  background: #efefef;
  border: 1px solid #ccc;
}

<button class="js-brute">
  Inject rows brute force
</button>
<button class="js-to">
  Inject rows timeout
</button>
<button class="js-clear">
  clear list
</button>

<pre></pre>
<div class="spinner"></div>

<ul>

</ul>

这篇关于Jquery一次循环和绑定10条记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆