SelectiveCollection.js

From disqus.com, 2 Months ago, written in JavaScript, viewed 3 times. This paste is a reply to dropdown.js from disqus.com - view diff
URL https://pastebin.freepbx.org/view/f8ff8847 Embed
Download Paste or View Raw
  1. define('home/collections/common/SelectiveCollection',[
  2.     'jquery',
  3.     'underscore',
  4.     'backbone',
  5. ], function (
  6.     $,
  7.     _,
  8.     Backbone
  9. ) {
  10.     'use strict';
  11.  
  12.     /**
  13.      * Builds a collection from a given ordered backer collection. Selects
  14.      * only certain items to a certain limit.
  15.      *
  16.      * The given backing collection of models will be scanned in order, each
  17.      * model checked for selectability. The first items that pass the
  18.      * selectability test will be inserted into this collection, up to the
  19.      * max number specified.
  20.      *
  21.      * If there are not enough items that pass the selectability test, there
  22.      * will be less than the specified number of items shown.
  23.      *
  24.      * Initialization Options:
  25.      *
  26.      * {Collection} toSelect (required) - A collection of models that may be
  27.      *     selected for this collection. These will be checked in order for
  28.      *     selectability, and the top <maxSize> will be added to this collection.
  29.      *
  30.      * {function} shouldSelect (optional) - A function that takes an item from
  31.      *     <toSelect> and returns a promise (or bool). If this promise is resolved, the
  32.      *     item will be added to this collection. If the promise is rejected, the
  33.      *     next item in <toSelect> will be checked for selectability. If not given,
  34.      *     all items will be assumed to be selectable.
  35.      *
  36.      * {number} maxSize (optional) - The number of items from <toSelect> that
  37.      *     should be selected (assuming there are enough that pass <shouldSelect>).
  38.      *     If not given, all the items from <toSelect> that pass <shouldSelect> will
  39.      *     be added to this collection.
  40.      *
  41.      * {function} order (optional) - The ordering to test the items in <toFeature> for
  42.      *     featurability. Takes the collection and converts to an array of models.
  43.      */
  44.     var SelectiveCollection = Backbone.Collection.extend({
  45.         initialize: function (models, options) {
  46.             if (models)
  47.                 // If models is defined, even as an empty array, this collection will be reset
  48.                 // with the given models after this initialization, which will overwrite any
  49.                 // selected items that have already resolved and been added.
  50.                 throw new Error('SelectiveCollection should be initialized with undefined models to be allowed to populate itself from a given toSelect collection');
  51.  
  52.             if (!options || !options.toSelect || !(options.toSelect instanceof Backbone.Collection))
  53.                 throw new Error('SelectiveCollection must be initialized with a toSelect collection');
  54.  
  55.             this.toSelect = options.toSelect;
  56.             this.shouldSelect = options.shouldSelect || this.shouldSelect;
  57.             this.maxSize = options.maxSize;
  58.             this.order = options.order || this.order;
  59.  
  60.             this.selectComplete = $.Deferred();
  61.  
  62.             if (this.toSelect.length)
  63.                 this.selectFrom(this.toSelect);
  64.             else
  65.                 this.toSelect.once('sync', this.selectFrom, this);
  66.         },
  67.  
  68.         selectFrom: function (collection) {
  69.             if (!collection.length) {
  70.                 this.completeSelection();
  71.                 return;
  72.             }
  73.  
  74.             this.maxSize = _.isNumber(this.maxSize) ?
  75.                 this.maxSize :
  76.                 collection.length;
  77.  
  78.             var stack = this.order(collection);
  79.             this.resolveSelectability(stack.shift(), stack);
  80.         },
  81.  
  82.         resolveSelectability: function (item, rest) {
  83.             if (!item) {
  84.                 this.completeSelection();
  85.                 return;
  86.             }
  87.  
  88.             var self = this;
  89.  
  90.             // Want to select items in the order they are checked for selectability. Should
  91.             // only check 1 item at a time for selectability. Once selectability has been
  92.             // resolved, can start checking the next item. Otherwise items may be selected
  93.             // out of order if a later check resolves first.
  94.             $.when(this.shouldSelect(item)).then(function (shouldSelect) {
  95.                 if (shouldSelect)
  96.                     self.select(item);
  97.  
  98.                 // If we need more items to fill this collection, check the next item in
  99.                 // order for selectibility
  100.                 if (self.length < self.maxSize)
  101.                     self.resolveSelectability(rest.shift(), rest);
  102.                 else
  103.                     self.completeSelection();
  104.             });
  105.         },
  106.  
  107.         /**
  108.          * Returns a promise which resolves when the selection process is complete.
  109.          * @returns {Promise}
  110.          */
  111.         isComplete: function () {
  112.             return this.selectComplete.promise();
  113.         },
  114.  
  115.         /**
  116.          * Marks the selection as completed.
  117.          */
  118.         completeSelection: function () {
  119.             this.selectComplete.resolve();
  120.         },
  121.  
  122.         /**
  123.          * Given an item, add it to this collection
  124.          */
  125.         select: function (model) {
  126.             // if already selected the max number of items, don't do anything
  127.             if (this.length >= this.maxSize) {
  128.                 this.completeSelection();
  129.                 return;
  130.             }
  131.  
  132.             this.add(model);
  133.         },
  134.  
  135.         /**
  136.          * Default shouldSelect function (always select) if not passed
  137.          * via `options.shouldSelect` in initialization
  138.          * @returns {boolean} should the model passed in be selected
  139.          */
  140.         shouldSelect: function (/* model */) {
  141.             return true;
  142.         },
  143.  
  144.         /**
  145.          * Default order function if not passed via `options.order` in
  146.          * initialization - simply returns the array of models in their
  147.          * current order in the collection
  148.          * @param  {Collection} collection the toSelect collection
  149.          * @returns {Array}            an array of Models in selection order
  150.          */
  151.         order: function (collection) {
  152.             return collection.toArray();
  153.         },
  154.     });
  155.  
  156.     return SelectiveCollection;
  157. });
  158.  
  159. // https://c.disquscdn.com/next/home/js/collections/common/SelectiveCollection.js

Replies to SelectiveCollection.js rss

Title Name Language When
ExtensibleCollection.js disqus.com javascript 2 Months ago.

Reply to "SelectiveCollection.js"

Here you can reply to the paste above