2013-02-23 3 views
28

I select2 jQuery-Plugin mit twitter Bootstrap bin mit. Es funktioniert gut für kleinere Anzahl von Elementen. Aber wenn die Liste riesig ist (mehr als 1500 Artikel), wird es wirklich langsamer. Es ist am langsamsten in IE.Select2 Performance für große Menge von Elementen

Normale Dropdownliste funktioniert sehr schnell mit mehr als 1500 Elementen. Gibt es Workarounds für diese Situation?

+1

Verwendung AJAX :) stattdessen die gesamten Daten des Ladens – Sedz

+7

Als Nebenwirkung: Ich fühle mich dies als eine Gedicht formatiert ist. Und bitte die Umschalttaste? – Arjan

Antwort

4

Denken Sie daran, Sie laden> 1500 tatsächliche Elemente auf die Seite in Form von <option> s, die am Ende Seite Leistung auch verletzen kann. Wie ein Benutzer in einem Kommentar vorgeschlagen hat, können Sie das Leistungsproblem lösen, indem Sie einen AJAX-Aufruf an einen Back-End-Dienst senden, der Ihre Werte zurückgibt.

Select2 Ajax how-to

21

Ich weiß, es ist eine alte Frage, aber ich wollte, was für mich gearbeitet teilen. Wenn Sie müssen laden Sie die große Liste (je nachdem, ob Sie von Grund auf neu oder Aufbauen auf jemand anderen Code, dies kann einfacher sein), verwenden Sie die minimumInputLength wie beschrieben here in der Dokumentation. Die riesige Liste der Optionen wird erst angezeigt, wenn der Benutzer ein paar Zeichen eingegeben hat. Dies reduziert den Performance-Hit beim Rendern stark, wenn das Dropdown-Menü "Select2" ausgewählt wird. Ich hoffe, das hilft!

+3

Einziger Nachteil ist, dass einige meiner Benutzer gerne in der Liste nach unten scrollen und dann ein paar Elemente auswählen, die nebeneinander liegen. Sie können dies zulassen, indem Sie 'closeOnSelect' setzen:' false'. Wenn Sie 'minimumInputLength' verwenden, kann der Benutzer nicht mehrere Elemente gleichzeitig auswählen, sondern nur eins nach dem anderen. –

+0

Großer Kommentar; Du machst einen sehr guten Punkt. – BammaHamma

+0

Wollte hinzufügen, dass die Seite geladen noch langsam sein kann, wenn die Seite viele Dropdown-Listen mit großen Listen hat – Anupam

35

Sie diese Arbeit in IE8 gut, auch mit Paginieren, die Vorschläge machen,

Code:

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

$(function() { 
    $('#e24').select2({ 
     // For demonstration purposes we first make 
     // a huge array of demo data (20 000 items) 
     // Heads up; for the _.map and _.filter function i use underscore (actually lo-dash) here 
     data: _.map(_.range(1, 20000), function (i) { 
      return { 
       id : i, 
       text: shuffle('te ststr ing to shuffle') + ' ' + i 
      }; 
     }), 

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

     // configure as multiple select 
     multiple: true, 

     // text for loading more results 
     formatLoadMore: 'Loading more...', 

     query: function (q) { 
      // pageSize is number of results to show in dropdown 
      var pageSize, results; 

      pageSize = 20; 
      results = _.filter(this.data, function (e) { 
       return (q.term === "" || e.text.toUpperCase().indexOf(q.term.toUpperCase()) >= 0); 
      }); 

      q.callback({ 
       results: results.slice((q.page - 1) * pageSize, q.page * pageSize), 

       // retrieve more when user hits bottom 
       more: results.length >= q.page * pageSize 
      }); 
     } 
    }); 
}); 

Arbeitsbeispiel mit 20000 Artikel hier: http://embed.plnkr.co/db8SXs/preview

plnkr einbetten nicht IE8 unterstützt so versuchen sie es stattdessen mit diesem Link auf IE8 aus: http://run.plnkr.co/plunks/db8SXs/

+1

Dies ist eine großartige Lösung. hatte ein Problem, wo die Möglichkeit von 200 Drop-downs auf dem Bildschirm auf einmal und mit mehr als x Elemente in den Dropdown-Listen verursachte lonnnnnnggg Seite lädt. Dies konnte es auf ein paar Sekunden statt 2 Minuten bringen. – yaegerbomb

+0

Vielen Dank für die Freigabe Ihres Codes. Wenn Sie noch in der Nähe sind, wie kann ich die Standardwerte auswählen? Leider, anders als vorher, läuft '$ ('# e24'). Select2 ('val', [" 150 "]);' nachdem Ihr Instanziierungscode nicht funktioniert. –

+1

Es ist möglich, wenn Sie den Wert vor der Initialisierung von select2 als z. '$ ('# e24'). val ([firstSelectedValue, secondSelectedValue) ' und add' initSelection: function (element, callback) { var data = []; $ (element.val(). Split ("")). Each (function() { Daten.push ({id: this, text: this}); }); Rückruf (Daten); }, ' innerhalb der select2 init gemäß select2 docs. Ich konnte es nicht mit z. 'val: [" 1 "," 2 "] though innerhalb des Initialisierers. Aktualisiert arbeiten PLNKR: [http://embed.plnkr.co/db8SXs/preview](http://embed.plnkr.co/db8SXs/preview) – MarcusAsplund

3

Dies ist eine sehr alte Frage und Antwort und sogar wir haben eine neuere Version von select2. aber wenn jemand versucht in optgroup zu suchen. kann diese Lösung versuchen.

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 
     }); 
    } 
    }); 
+1

Der Held, den wir brauchen – jake