Подтвердить что ты не робот

Производительность Select2 для большого набора элементов

Я использую select2 jquery plugin с twitter bootstrap. Он отлично работает для меньшего количества предметов. Но когда список огромен (более 1500 предметов), он действительно замедляется. Это медленнее в IE.

Нормальный Dropdownlist работает очень быстро с более чем 1500 элементами. Существуют ли какие-либо обходные пути для этой ситуации?

4b9b3361

Ответ 1

Вы можете сделать это хорошо даже в IE8 с нумерацией предложений,

Код:

// Function to shuffle the demo data
function shuffle(str) {
  return str
    .split('')
    .sort(function() {
      return 0.5 - Math.random();
  })
.join('');
}

// For demonstration purposes we first make
// a huge array of demo data (20 000 items)
// HEADS UP; for the _.map function i use underscore (actually lo-dash) here
function mockData() {
  return _.map(_.range(1, 20000), function(i) {
    return {
      id: i,
      text: shuffle('te ststr ing to shuffle') + ' ' + i,
    };
  });
}
(function() {
  // init select 2
  $('#test').select2({
    data: mockData(),
    placeholder: 'search',
    multiple: true,
    // query with pagination
    query: function(q) {
      var pageSize,
        results,
        that = this;
      pageSize = 20; // or whatever pagesize
      results = [];
      if (q.term && q.term !== '') {
        // HEADS UP; for the _.filter function i use underscore (actually lo-dash) here
        results = _.filter(that.data, function(e) {
          return e.text.toUpperCase().indexOf(q.term.toUpperCase()) >= 0;
        });
      } else if (q.term === '') {
        results = that.data;
      }
      q.callback({
        results: results.slice((q.page - 1) * pageSize, q.page * pageSize),
        more: results.length >= q.page * pageSize,
      });
    },
  });
})();

рабочий пример с 20000 элементами здесь: http://embed.plnkr.co/db8SXs/preview

Встраивание plnkr не поддерживает IE8, поэтому попробуйте его на IE8 по этой ссылке: http://run.plnkr.co/plunks/db8SXs/

Ответ 2

Я знаю, это старый вопрос, но я хотел поделиться тем, что сработало для меня. Если вы должны предварительно загрузить большой список (в зависимости от того, начинаете ли вы с нуля или создаете код другого пользователя, это может быть проще), используйте minimumInputLength, как описано здесь в документации. Огромный список опций не отображается, пока пользователь не набрал пару символов. Это значительно снижает производительность при рендеринге при выделении выпадающего меню Select2. Надеюсь, что это поможет!

Ответ 3

Так что имейте в виду, что вы загружаете> 1500 реальных элементов на страницу в виде <option> s, что также может снизить производительность страницы. Как предложил пользователь в комментарии, вы можете решить проблему с производительностью, вызвав AJAX-вызов серверной службы, которая будет возвращать ваши значения.

Select2 Ajax с практическими рекомендациями

Ответ 4

Это очень старый вопрос и ответ, и даже у нас есть более новая версия select2. но если кто-то пытается искать в optgroup тоже. может попробовать это решение.

http://jsfiddle.net/na1zLkz3/4/

    // Function to shuffle the demo data 
var shuffle = function (str) {
    return str.split('').sort(function () {
      return 0.5 - Math.random();
    }).join('');
  };

// For demonstration purposes we first make
// a huge array of demo data (20 000 items)
// HEADS UP; for the _.map function i use underscore (actually lo-dash) here
var mockData = function () {
    var array = _.map(_.range(1, 10), function (i) {
        return {
          id  : i,
          text: shuffle('te ststr ing to shuffle') + ' ' + i
        };
      });
    return array;
  };
  var mockData1 = function () {
    var array = _.map(_.range(10, 15), function (i) {
        return {
          id  : i,
          text: shuffle('te ststr ing to shuffle') + ' ' + i
        };
      });
    return array;
  };
  var mockData2 = function () {
    var array = _.map(_.range(15, 20), function (i) {
        return {
          id  : i,
          text: shuffle('te ststr ing to shuffle') + ' ' + i
        };
      });
    return array;
  };
  // create demo data
  var dummyData = mockData();
  var dummyData1 = mockData1();
  var dummyData2 = mockData2();
  dummyData.push({
  text: 'canada',
  children: dummyData1
  });
  dummyData.push({
  text: 'USA',
  children: dummyData2
  });

  // init select 2
  $('#ddlCar').select2({
    data             : dummyData,
    // init selected from elements value
    initSelection    : function (element, callback) {
      var initialData = [];
      $(element.val().split(",")).each(function () {
        initialData.push({
          id  : this,
          text: this
        });
      });
      callback(initialData);
    },

    // NOT NEEDED: These are just css for the demo data
    dropdownCssClass : 'capitalize',
    containerCssClass: 'capitalize',

    // NOT NEEDED: text for loading more results
    formatLoadMore   : function() {return 'Loading more...'},

    // query with pagination
    query            : function (q) {
      var pageSize,
        results;
      pageSize = 20; // or whatever pagesize
      var results  = [];
      if (q.term && q.term !== "") {
        // HEADS UP; for the _.filter function i use underscore (actually lo-dash) here
        var results = this.data;
        var results = _.filter(results, function (e) {
            if(typeof e.children != 'undefined')
          {
            subresults = _.filter(e.children, function (f) {
                return (f.text.toUpperCase().indexOf(q.term.toUpperCase()) >= 0);
            });
            if(subresults.length > 0)
                return true;
            return false;
          }
          return (e.text.toUpperCase().indexOf(q.term.toUpperCase()) >= 0);
        });
        newresults = [];
        for (var i = 0, len = results.length; i < len; i++) {
        newresults[i] = {};
        if(typeof results[i].text != 'undefined')
            newresults[i].text = results[i].text;
        if(typeof results[i].id != 'undefined')
            newresults[i].id = results[i].id;
        if(typeof results[i].children != 'undefined')
        {
            newresults[i].children = results[i].children;
            newresults[i].children = _.filter(newresults[i].children, function (f)                          {
                return (f.text.toUpperCase().indexOf(q.term.toUpperCase()) >= 0);
            });
        }
      }
      results = newresults;
      } else if (q.term === "") {
        results = this.data;

      }

      q.callback({
        results: results.slice((q.page - 1) * pageSize, q.page * pageSize),
        more   : results.length >= q.page * pageSize
      });
    }
  });

Ответ 5

Вот рабочая версия для Select2 v4

Основываясь на ответе здесь: и изменил его, чтобы поиск работал с lo-dash

$(function () {
    items = []
    for (var i = 0; i < 1000; i++) {
        items.push({ id: i, text : "item " + i})
    }

    pageSize = 50

    jQuery.fn.select2.amd.require(["select2/data/array", "select2/utils"],

    function (ArrayData, Utils) {
        function CustomData($element, options) {
            CustomData.__super__.constructor.call(this, $element, options);
        }
        Utils.Extend(CustomData, ArrayData);

        CustomData.prototype.query = function (params, callback) {

            var results = [];
            if (params.term && params.term !== '') {
              results = _.filter(items, function(e) {
                return e.text.toUpperCase().indexOf(params.term.toUpperCase()) >= 0;
              });
            } else {
              results = items;
            }

            if (!("page" in params)) {
                params.page = 1;
            }
            var data = {};
            data.results = results.slice((params.page - 1) * pageSize, params.page * pageSize);
            data.pagination = {};
            data.pagination.more = params.page * pageSize < results.length;
            callback(data);
        };

        $(document).ready(function () {
            $("select").select2({
                ajax: {},
                dataAdapter: CustomData
            });
        });
    })
});

JsFiddle: http://jsfiddle.net/nea053tw/

Изменить: Скрипка изменена.

Ответ 6

Самая простая работа для меня это:

$(".client_id").select2({
 minimumInputLength: 2
  });

Вы можете изменить значениеimumInputLength по своему желанию.

Таким образом, select2 не должен показывать весь список, скорее он даст результат только после того, как набрано фиксированное количество символов. Хотя у вас все еще есть большой массив списков на переднем конце кода.

Кроме того, если вы используете allowClear, вы должны объявить placehodler следующим образом:

$(".client_id").select2({
            minimumInputLength: 2,
            allowClear: true,
            placeholder: '--Select Client--'
        });

Проверьте документацию здесь http://select2.github.io/select2

Ответ 7

У меня была та же проблема с 51000 выбранными опциями..... я решил ее с отличным разрешением ::

https://stackoverflow.com/info/53702468/select2-large-number-of- 
records/53702660#53702660

select2 + большое количество записей