UNPKG

backbone-fractal

Version:

Lightweight composite views for Backbone

163 lines (161 loc) 6.99 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "underscore", "./underscore-compat", "backbone"], factory); } })(function (require, exports) { "use strict"; exports.__esModule = true; var underscore_1 = require("underscore"); var underscore_compat_1 = require("./underscore-compat"); var backbone_1 = require("backbone"); var defaultIterationOptions = { placeOnly: false, reverse: false }; var CompositeView = /** @class */ (function (_super) { __extends(CompositeView, _super); function CompositeView() { return _super !== null && _super.apply(this, arguments) || this; } CompositeView.prototype.render = function () { this.beforeRender(); this.detachSubviews(); this._resetContainer(); this.placeSubviews(); this.afterRender(); return this; }; CompositeView.prototype.beforeRender = function () { return this; }; CompositeView.prototype.renderContainer = function () { return this; }; CompositeView.prototype.afterRender = function () { return this; }; CompositeView.prototype.remove = function () { this.clearSubviews(); delete this._containers; _super.prototype.remove.call(this); return this; }; /** * Invariant: each subview must appear at most once in this list. */ CompositeView.prototype.subviews = function () { return []; }; CompositeView.prototype.clearSubviews = function () { return this.forEachSubview(_removeSubview, { reverse: true }); }; CompositeView.prototype.detachSubviews = function () { return this.forEachSubview(_detachSubview, { reverse: true }); }; CompositeView.prototype.placeSubviews = function () { // No need to detach the subview first. // Each subview is unique, so jQuery moves rather than copies it. return this.forEachSubview(_placeSubview, { placeOnly: true }); }; CompositeView.prototype.forEachSubview = function (iteratee, options) { var _this = this; var _iteratee = function (args) { return iteratee.apply(_this, args); }; var _a = options || defaultIterationOptions, placeOnly = _a.placeOnly, reverse = _a.reverse; var iterator = reverse ? underscore_compat_1.eachRight : underscore_1.each; var list = this._getSubviews(placeOnly); iterator(list, _iteratee); return this; }; CompositeView.prototype._resetContainer = function () { this._containers = {}; return this.renderContainer(); }; CompositeView.prototype._getSubviews = function (applyChecks) { var normalize = this._normalizeSubview.bind(this, applyChecks); if (!this._containers) this._resetContainer(); return underscore_1.compact(underscore_1.map(underscore_1.result(this, 'subviews'), normalize)); }; CompositeView.prototype._normalizeSubview = function (applyChecks, sv) { sv = this._resolve(sv); if (underscore_1.isUndefined(sv)) return null; if (sv instanceof backbone_1.View) return [sv, this.$el, this.defaultPlacement]; var view = sv.view, selector = sv.selector, place = sv.place; if (applyChecks && !underscore_1.isUndefined(place) && !this._resolve(place)) { return null; } view = this._resolve(view); if (!(view instanceof backbone_1.View)) return null; if (underscore_1.isFunction(selector)) { selector = selector.call(this); } if (underscore_1.isString(selector)) { var method = sv.method; return this._normalizeSelectorSubview(view, selector, method); } else { var method = sv.method; return this._normalizeRootSubview(view, method); } }; CompositeView.prototype._normalizeRootSubview = function (view, method) { if (underscore_1.isFunction(method)) { method = method.call(this); } if (method && method !== 'append' && method !== 'prepend') { throw new TypeError("Selector empty or attempting jQuery method " + ("." + method + "() on the root element of a CompositeView.")); } return [view, this.$el, method || this.defaultPlacement]; }; CompositeView.prototype._normalizeSelectorSubview = function (view, selector, method) { if (underscore_1.isFunction(method)) method = method.call(this); var container = this._containers[selector]; if (!container) { this._containers[selector] = container = this.$(selector).first(); } return [view, container, method || this.defaultPlacement]; }; CompositeView.prototype._resolve = function (handle) { if (underscore_1.isString(handle)) handle = underscore_1.result(this, handle); if (underscore_1.isFunction(handle)) handle = handle.call(this); return handle; }; return CompositeView; }(backbone_1.View)); exports["default"] = CompositeView; underscore_1.extend(CompositeView.prototype, { defaultPlacement: 'append' }); function _removeSubview(view) { view.remove(); } exports._removeSubview = _removeSubview; function _detachSubview(view) { view.$el.detach(); } exports._detachSubview = _detachSubview; function _placeSubview(subview, container, method) { var insert = (container[method]); insert.call(container, subview.el); } exports._placeSubview = _placeSubview; }); //# sourceMappingURL=composite-view.js.map