Source: filtering-collection.js

/*
 * Copyright 2013-2017 Hewlett Packard Enterprise Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

/**
 * @module js-whatever/js/filtering-collection
 */
define([
    'underscore',
    'backbone'
], function(_, Backbone) {
    'use strict';

    function getTrackedAttributes(trackedModel) {
        return this.attributes
            ? trackedModel.pick.apply(trackedModel, this.attributes)
            : trackedModel.attributes;
    }

    function createTrackingModel(trackedModel) {
        return new this.model(getTrackedAttributes.call(this, trackedModel), {trackedModel: trackedModel});
    }

    function getTrackingModel(trackedModel) {
        return this.find(function(currentModel) {
            return currentModel.trackedModel === trackedModel;
        });
    }

    function getFilteredModels() {
        var filteredModels = this.collection.filter(function(model) {
            return this.modelFilter(model, this.filters);
        }, this);

        return _.map(filteredModels, function(model) {
            return createTrackingModel.call(this, model);
        }, this);
    }

    function removeModel(model) {
        this.remove(model);
        model.stopListening();
    }

    /**
     * @callback module:js-whatever/js/filtering-collection.FilteringCollection~modelFilter
     * @param {Backbone.Model} model The model to check against the filter
     * @param {Object} filters Filters data
     * @returns {Boolean} True if the model passes the filter, false if not
     */
    /**
     * @typedef module:js-whatever/js/filtering-collection.FilteringCollection~FilteringCollectionOptions
     * @property {Backbone.Collection} collection The collection to track
     * @property {module:js-whatever/js/filtering-collection.FilteringCollection~modelFilter} modelFilter
     * @property {Object} [filters={}] Initial filters data which will be passed to the modelFilter
     */
    /**
     * @name module:js-whatever/js/filtering-collection.FilteringCollection
     * @desc Collection which tracks another collection. Models added to the tracked collection are only added to the
     * FilteringCollection if they pass the modelFilter function. If the tracked model changes, the modelFilter is applied
     * again and if it passes the new attributes are set on the tracking model, or if it fails the model is removed.
     * Models removed from the tracked collection are removed from the FilteringCollection.
     * @constructor
     * @param {Backbone.Model[]} models Initial models
     * @param {module:js-whatever/js/filtering-collection.FilteringCollection~FilteringCollectionOptions} Options for the filtering collection
     * @extends Backbone.Collection
     */
    return Backbone.Collection.extend(/** @lends module:js-whatever/js/filtering-collection.FilteringCollection.prototype */{
        initialize: function(models, options) {
            this.attributes = options.attributes;
            this.collection = options.collection;
            this.filters = options.filters || {};
            this.modelFilter = options.modelFilter;

            this.listenTo(this.collection, 'add', function(trackedModel) {
                if(this.modelFilter(trackedModel, this.filters)) {
                    this.add(createTrackingModel.call(this, trackedModel));
                }
            });

            this.listenTo(this.collection, 'change', function(trackedModel) {
                var existingModel = getTrackingModel.call(this, trackedModel);

                if(existingModel) {
                    if(this.modelFilter(trackedModel, this.filters)) {
                        existingModel.set(getTrackedAttributes.call(this, trackedModel));
                    } else {
                        removeModel.call(this, existingModel);
                    }
                } else if(this.modelFilter(trackedModel, this.filters)) {
                    this.add(createTrackingModel.call(this, trackedModel));
                }
            });

            this.listenTo(this.collection, 'remove', function(trackedModel) {
                var trackingModel = getTrackingModel.call(this, trackedModel);

                if(trackingModel) {
                    removeModel.call(this, trackingModel);
                }
            });

            this.listenTo(this.collection, 'reset', function() {
                this.reset(getFilteredModels.call(this));
            });

            _.each(getFilteredModels.call(this), function(model) {
                models.push(model);
            });
        },

        /**
         * @desc Updates the filters data to the method parameter and re-filters the collection
         * @param {Object} filters New filters data
         */
        filter: function(filters) {
            this.filters = filters;
            this.reset(getFilteredModels.call(this));
        },

        model: Backbone.Model.extend({
            initialize: function(attributes, options) {
                this.trackedModel = options.trackedModel;
            }
        })
    });
});
Copyright 2013-2018 Micro Focus International plc. Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
Documentation generated by JSDoc 3.4.3 on Thu Jun 21st 18:04 2018 using the DocStrap template.