View
A View is simply a JavaScript object that represents a logical chunk of UI in the DOM. The general idea is to organize your interface into logical views, backed by models, each of which can be updated independently when the model changes, without having to redraw the page. This allows you to bind your view's render
function to the model's "change"
event — and now everywhere that model data is displayed in the UI, it is always immediately up to date.
Properties
attributes
view.attributes
A hash of attributes that will be set as HTML DOM element attributes on the view's el
(id, class, data-properties, etc.), or a function that returns such a hash.
el
view.el
All views have a DOM element at all times (the el
property), whether they've already been inserted into the page or not. In this fashion, views can be rendered at any time, and inserted into the DOM all at once, in order to get high-performance UI rendering with as few reflows and repaints as possible.
this.el
can be resolved from a DOM selector string or an Element; otherwise it will be created from the view's tagName
, className
, id
and attributes
properties. If none are set, this.el
is an empty div
, which is often just fine. An el
reference may also be passed in to the view's constructor.
const ShapeView = mvc.View.extend({
el: 'body'
});
const shape = new ShapeView();
console.log(shape.el) // <body>...</body>
Methods
delegateEvents()
delegateEvents([events])
Provide declarative callbacks for DOM events within a view. If an events hash is not passed directly, uses this.events
as the source. Events are written in the format { "event selector": "callback" }
. The callback may be either the name of a method on the view, or a direct function body. Omitting the selector causes the event to be bound to the view's root element (this.el
). By default, delegateEvents
is called within the View's constructor for you, so if you have a simple events hash, all of your DOM events will always already be connected, and you will never have to call this function yourself.
The events
property may also be defined as a function that returns an events hash, to make it easier to programmatically define your events, as well as inherit them from parent views.
Using delegateEvents
provides a number of advantages. All attached callbacks are bound to the view before being handed off, so when the callbacks are invoked, this
continues to refer to the view object. When delegateEvents
is run again, perhaps with a different events
hash, all callbacks are removed and delegated afresh — useful for views which need to behave differently when in different modes.
A single-event version of delegateEvents
is available as delegate
. In fact, delegateEvents
is simply a multi-event wrapper around delegate
. A counterpart to undelegateEvents
is available as undelegate
.
events()
view.events or view.events()
The events hash (or method) can be used to specify a set of DOM events that will be bound to methods on your View through delegateEvents
. JointJS will automatically attach the event listeners at instantiation time, right before invoking initialize
.
extend()
mvc.View.extend(properties, [classProperties])
Create a custom view class. You'll want to override the render
function, specify your declarative events
, and perhaps the tagName
, className
, or id
of the View's root element.
const ShapeRow = mvc.View.extend({
tagName: "li",
className: "shape-row",
events: {
"click .icon": "open",
"click .button.edit": "openEditDialog"
},
initialize: function() {
this.listenTo(this.model, "change", this.render);
},
render: function() {
...
}
});
Properties like tagName
, id
, className
, el
, and events
may also be defined as a function, if you want to wait to define them until runtime.
initialize()
There are several special options that, if passed, will be attached directly to the view: model
, collection
, el
, id
, className
, tagName
, attributes
and events
. If the view defines an initialize
function, it will be called when the view is first created. Initialize is an empty function by default. Override it with your own initialization logic.
If you'd like to create a view that references an element already in the DOM, pass in the element as an option: new View({ el: existingElement })
preinitialize()
For use with views as ES classes. If you define a preinitialize
method, it will be invoked when the view is first created, before any instantiation logic is run. preinitialize
is an empty function by default. You can override it with a function or object.
class View extends mvc.View {
preinitialize({ autoRender }) {
this.autoRender = autoRender;
}
initialize() {
if (this.autoRender) {
this.listenTo(this.model, 'change', this.render);
}
}
}
remove()
view.remove()
Removes a view and its el
from the DOM, and calls stopListening
to remove any bound events that the view has listenTo
'd.
render()
view.render()
render
is the core function that your view should override, in order to populate its element (this.el
), with the appropriate HTML. The convention is for render to always return this
to enable chained calls.
setElement()
view.setElement(element)
Change the view's element (this.el
property) and re-delegate the view's events on the new element.
undelegateEvents()
undelegateEvents()
Removes all of the view's delegated events. Useful if you want to disable or remove a view from the DOM temporarily.