backbone-fractal
Version:
Lightweight composite views for Backbone
163 lines (161 loc) • 6.99 kB
JavaScript
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