/**
* @copyright 2015 Tridium, Inc. All Rights Reserved.
* @author Logan Byam
*/
/**
* @module nmodule/webEditors/rc/wb/table/model/ComponentTableModel
*/
define([ 'baja!',
'log!nmodule.webEditors.rc.wb.table.model.ComponentTableModel',
'underscore',
'nmodule/webEditors/rc/fe/baja/util/typeUtils',
'nmodule/webEditors/rc/wb/table/model/ComponentSource',
'nmodule/webEditors/rc/wb/table/model/TableModel',
'nmodule/webEditors/rc/wb/table/model/source/ContainerComponentSource' ], function (
baja,
log,
_,
typeUtils,
ComponentSource,
TableModel,
ContainerComponentSource) {
'use strict';
var isComponent = typeUtils.isComponent,
logError = log.severe.bind(log),
DEFAULT_CHANGE_EVENT_THROTTLE_MS = 250;
/**
* API Status: **Development**
*
* Table model where each row in the table represents a `Component`.
*
* A `ComponentTableModel` is backed by a `ComponentSource`, which provides
* the list of `Components` to build into table rows.
*
* @class
* @extends module:nmodule/webEditors/rc/wb/table/model/TableModel
* @alias module:nmodule/webEditors/rc/wb/table/model/ComponentTableModel
* @param {Object|baja.Component} params parameters object, or a `Component`
* if no parameters required.
* @param {baja.Component|module:nmodule/webEditors/rc/wb/table/model/ComponentSource} params.componentSource
* the source of components to build into table rows.
* If a `Component` is given it will just be wrapped in a `ComponentSource`
* with no parameters.
* @param {Array.<module:nmodule/webEditors/rc/wb/table/model/Column>} params.columns
*/
var ComponentTableModel = function ComponentTableModel(params) {
params = baja.objectify(params, 'componentSource');
var that = this,
componentSource = params.componentSource,
rowsChangedEventDelay = params.rowsChangedEventDelay;
if (isComponent(componentSource)) {
componentSource = new ContainerComponentSource(componentSource);
}
if (!(componentSource instanceof ComponentSource)) {
throw new Error('Component or ComponentSource required');
}
if (_(rowsChangedEventDelay).isUndefined()) {
rowsChangedEventDelay = DEFAULT_CHANGE_EVENT_THROTTLE_MS;
}
that.$componentSource = componentSource;
that.$bufferedChanges = [];
that.$rowsChangedEventDelay = rowsChangedEventDelay;
that.$emitThrottledRowsChangedEvent = _.throttle(function () {
if (that.$bufferedChanges.length) {
var rows = [];
_.each(that.$bufferedChanges, function (comp) {
var rowAndIndex = that.$getRowForSubject(comp);
if (rowAndIndex) {
rows.push(rowAndIndex.row);
}
});
if (rows.length) { that.emit('rowsChanged', rows); }
that.$bufferedChanges = [];
}
}, rowsChangedEventDelay, { leading: false });
componentSource
.on('added', function (comps) {
that.insertRows(comps).catch(logError);
})
.on('removed', function (comps) {
_.each(comps, function (comp) {
var obj = that.$getRowForSubject(comp);
if (obj) { that.removeRows([ obj.row ]).catch(logError); }
});
})
.on('changed', function (comp) {
if (!(_.contains(that.$bufferedChanges, comp))) {
that.$bufferedChanges.push(comp);
that.$emitThrottledRowsChangedEvent();
}
});
TableModel.call(that, {
columns: params.columns,
rows: componentSource.getComponents()
});
};
ComponentTableModel.prototype = Object.create(TableModel.prototype);
ComponentTableModel.prototype.constructor = ComponentTableModel;
/**
* Find the first row that has the given subject (identity equal).
*
* @private
* @param {*} subject
* @returns {Object} object with `row` (the actual Row) and `index`
* properties, or undefined if not found
*/
ComponentTableModel.prototype.$getRowForSubject = function (subject) {
var rows = this.getRows(), i;
for (i = 0; i < rows.length; i++) {
if (rows[i].getSubject() === subject) {
return { row: rows[i], index: i };
}
}
};
/**
* Get the `ComponentSource` backing this table model.
*
* @returns {module:nmodule/webEditors/rc/wb/table/model/ComponentSource}
*/
ComponentTableModel.prototype.getComponentSource = function () {
return this.$componentSource;
};
/**
* Return the delay (in milliseconds) used by throttled 'rowsChanged' event
* emission function.
*
* @private
*/
ComponentTableModel.prototype.$getRowsChangedEventDelay = function () {
return this.$rowsChangedEventDelay;
};
return (ComponentTableModel);
});