Plato on Github
Report Home
compositeview.js
Maintainability
71.68
Lines of code
128
Difficulty
20.16
Estimated Errors
0.75
Function weight
By Complexity
By SLOC
// Composite View // -------------- // Used for rendering a branch-leaf, hierarchical structure. // Extends directly from CollectionView and also renders an // an item view as `modelView`, for the top leaf Marionette.CompositeView = Marionette.CollectionView.extend({ constructor: function(options){ Marionette.CollectionView.apply(this, slice(arguments)); this.itemView = this.getItemView(); }, // Configured the initial events that the composite view // binds to. Override this method to prevent the initial // events, or to add your own initial events. _initialEvents: function(){ if (this.collection){ this.listenTo(this.collection, "add", this.addChildView, this); this.listenTo(this.collection, "remove", this.removeItemView, this); this.listenTo(this.collection, "reset", this._renderChildren, this); } }, // Retrieve the `itemView` to be used when rendering each of // the items in the collection. The default is to return // `this.itemView` or Marionette.CompositeView if no `itemView` // has been defined getItemView: function(item){ var itemView = Marionette.getOption(this, "itemView") || this.constructor; if (!itemView){ throwError("An `itemView` must be specified", "NoItemViewError"); } return itemView; }, // Serialize the collection for the view. // You can override the `serializeData` method in your own view // definition, to provide custom serialization for your view's data. serializeData: function(){ var data = {}; if (this.model){ data = this.model.toJSON(); } return data; }, // Renders the model once, and the collection once. Calling // this again will tell the model's view to re-render itself // but the collection will not re-render. render: function(){ this.isRendered = true; this.isClosed = false; this.resetItemViewContainer(); this.triggerBeforeRender(); var html = this.renderModel(); this.$el.html(html); // the ui bindings is done here and not at the end of render since they // will not be available until after the model is rendered, but should be // available before the collection is rendered. this.bindUIElements(); this.triggerMethod("composite:model:rendered"); this._renderChildren(); this.triggerMethod("composite:rendered"); this.triggerRendered(); return this; }, _renderChildren: function(){ if (this.isRendered){ Marionette.CollectionView.prototype._renderChildren.call(this); this.triggerMethod("composite:collection:rendered"); } }, // Render an individual model, if we have one, as // part of a composite view (branch / leaf). For example: // a treeview. renderModel: function(){ var data = {}; data = this.serializeData(); data = this.mixinTemplateHelpers(data); var template = this.getTemplate(); return Marionette.Renderer.render(template, data); }, // Appends the `el` of itemView instances to the specified // `itemViewContainer` (a jQuery selector). Override this method to // provide custom logic of how the child item view instances have their // HTML appended to the composite view instance. appendHtml: function(cv, iv){ var $container = this.getItemViewContainer(cv); $container.append(iv.el); }, // Internal method to ensure an `$itemViewContainer` exists, for the // `appendHtml` method to use. getItemViewContainer: function(containerView){ if ("$itemViewContainer" in containerView){ return containerView.$itemViewContainer; } var container; if (containerView.itemViewContainer){ var selector = _.result(containerView, "itemViewContainer"); container = containerView.$(selector); if (container.length <= 0) { throwError("The specified `itemViewContainer` was not found: " + containerView.itemViewContainer, "ItemViewContainerMissingError"); } } else { container = containerView.$el; } containerView.$itemViewContainer = container; return container; }, // Internal method to reset the `$itemViewContainer` on render resetItemViewContainer: function(){ if (this.$itemViewContainer){ delete this.$itemViewContainer; } } });