This document summarizes some key aspects of the Marionette library:
- Marionette provides common design patterns for building large-scale Backbone applications with features like nested views, view rendering on model changes, and region-based view management.
- The library includes classes like ItemView, CollectionView, and CompositeView that automatically render views based on model or collection data. It also has a messaging bus for application-level events.
- The messaging bus includes an event aggregator for pub/sub messaging, commands for triggering actions, and a request/response system for requesting data without tight coupling between components.
6. • Simple :)
• Too easy to go in wrong direction
• No main Application class
• No nesting of views
• No layouts (header/footer/sidebar/content etc)
• Method render does nothing by default
• Memory management
CONS
8. • Has a bunch of common design patterns
• Lowers amount of standard code because of view
types
• Has nested views
• Manages memory
• Combines event-driven architecture and event
aggregator
15. Marionette.ItemView
• View is rendered based on model data
• “model” attribute
• “template” attribute
• is rendered automatically
• modelEvents – view methods are called on model
events
16. UI OBJECT
UI hash in the view maps UI elements by their jQuery
selectors
17. Marionette.CollectionView
• View is rendered based on Collection data
• Automatic re-render on add/remove/reset/etc events
• childView attribute is automatically instantiated and
linked with model
23. REGION
• View intended to manage the lifecycle of other views
• Renders view instance and adds it to DOM
• It’s a bridge between DOM and backbone
• Nested regions - LayoutView class
28. MESSAGING BUS
• Event - app-level events
• Commands - run commands
• Request/Response - request of specific
values/states
29. EVENT AGGREGATOR
• pub/sub
• trigger/bind
• Notifies the app about events in different parts
(“user:logged-in”)
• App level events are like global function calls
• Different event types, namespaces define the
semantics
31. COMMANDS
Commands are used to make any component
tell another component to perform an action
without a direct reference to it.
• Subscribe for a command - only once
• Example: Save command
• cmd-s
• Clicking a toolbar button
• Choosing File => Save from the menubar
33. REQUEST / RESPONSE
• Request Response is a means for any component
to request information from another component
without being tightly coupled.
• For app level data (e. g. shopping cart status)
• Requests have intention
• The requests are 'one-to-one'
35. Backbone.Radio.channel
// Get a reference to the channel named 'user'
var userChannel = Backbone.Radio.channel('user');
userChannel.on('some:event', function() {
console.log('An event has happened!');
});
userChannel.reply('some:request', 'food is good');
userChannel.trigger('some:event');
Combination of Backbone.Events and
Radio.Requests
36. SUMMARY
MESSAGING BUS
• Application.vent - instance of Backbone.Wreqr.EventAggregator.
pub/sub.
• Application.commands - instance of Backbone.Wreqr.Commands.
Subscribe to command execution - once
• Application.reqres - instance of
Backbone.Wreqr.RequestResponse. Only one subscriber
performs the request
• Backbone.Radio.channel
37. • Child views - Backbone.BabySitter
• Marionette.RegionManager
• Marionette.TemplateCache
OTHER COOL THINGS FOR
VIEWS MANAGEMENT
all JS frameworks have pros & cons
no silver bullet
choose the right tool depending on task
-
-
-
-
Application wrapper for a plain Javascript object with a start() method. This can be used to accomplish tasks before the rest of your application begins.
MyApp.on("before:start", function(options){
options.moreData = "…";
});
MyApp.on("start", function(options){
if (Backbone.history){
Backbone.history.start();
}
});
--
Application regions
This feature is deprecated. Instead of using the Application as the root of your view tree, you should use a Layout View. To scope your Layout View to the entire document, you could set its el to 'body'.
V2.0
Modularity is ok
-
Several types of views; bb has the only one – not flexible
Auto render on model change – will show later
Close() method helps avoiding memory leaks
Underscore – by default
Handlebars templates have logic
Template helpers help making templates smarter
When this attribute is present - its contents will be mixed in to the data object - from the
serializeData method. Create helper methods that can be called from within the templates.
As calculated values.
Prefix the data you need with "this". Gives you all of the methods and attributes of the serialized data object, including the other helper methods.
So helper methods can be called from the templates
For one element
Is cached attributes which are mapped to jq object (alias)
To access the same UI element more than once in your view's code.
simply reference it by this.ui.alias
For collection’s add/remove/sort – renders through documentFragment
loop through all of the models in the collection, render each of them using a specified childView,
then append the results of the child view's el to the collection view's el.
By default the CollectionView will maintain a sorted collection's order
in the DOM. This behavior can be disabled by specifying {sort: false} on initialize.
-
Collection with a template:
- both a branch and leaf in a tree structure
- a collection needs to be rendered within a wrapper template
Similar to the events hash, views can specify a configuration hash for collections and models.
how to deal with zombie views
How many alerts can we see?
Instance 1 of zombieView out of scope after the 2nd is created
JS garbage collector can delete 1st instance -> zombieView should get inactive and stop listening to model events
But we get 2 alerts!
Due to model event listener: this.render -> ‘on’ callback => model saves direct link to view instance
So both views react to model events
Solve that: in bb – set method close(), clean/unbind/stopListening
In Marionette: regions!
---
Вопрос: сколько alert() мы увидим?
Поскольку мы используем переменную zombieView для обоих экземпляров представления, первый экземпляр окажется вне области видимости сразу после создания второго экземпляра. Это даст возможность «сборщику мусора» JavaScript уничтожить первый экземпляр, в результате чего представление утратит активность и перестанет реагировать на события изменения модели. Тем не менее если мы запустим этот код, то увидим окно дважды!
Эта проблема вызвана привязкой события модели в методе initialize view. Каждый раз, когда мы передаем this.render в качестве функции callback методу on модели, сама модель получает прямую ссылку на экземпляр view. Наличие этой ссылки в модели приводит к тому, что при присваивании нового экземпляра представления переменной zombieView первое представление остается в области видимости.
Поскольку второе представление появляется в области видимости в тот момент, когда первое представление продолжает находиться в ней, оба представления реагируют на изменение данных модели.
Regions provide consistent methods to manage, show and destroy views.
We bind it to DOM el and it renders view there
Using the LayoutView class you can create nested regions.
auto destroy()
-
You can also add regions via LayoutViews
To scope your Layout View to the entire
document, you could set its el to 'body'. This might look something like the following:
var RootView = Marionette.LayoutView.extend({
el: 'body',
regions: {menu: ‘#menu’, ….}
});
attach an instance of the RootView to your Application instance.
app.rootView = new RootView();
Event-driven architecture
bb.Wreqr – old – deprecated in M3
bb.Radio – isn’t a dependency yet; small snippet to include
--
Clone this repository or install via Bower or npm.
bower install backbone.radio
npm install backbone.radio
A shim to replace Backbone.Wreqr with Backbone.Radio in Marionette. Requires Marionette v2.1+
software architecture model for communicating between two systems. The idea is that instead of referencing each other directly, system components are able to send messages through a shared mediator object.
3 types of events
More complex events comparing to bb
--
Application.vent - instance of Backbone.Wreqr.EventAggregator. pub/sub.
Application.commands - instance of Backbone.Wreqr.Commands. Подписаться на исполнение команды - 1 раз
Application.reqres - instance of Backbone.Wreqr.RequestResponse. Исполняет запрос только один подписчик
Mediator object
Passively sharing info between the pieces of an app when events occur
Global – we can go the wrong way
Add namespaces to events – help sorting things out
Application.vent - instance of Backbone.Wreqr.EventAggregator.
Command pattern
Application.commands – instance of Backbone.Wreqr.Commands
During 2015, Commands were deprecated from Backbone.Radio as part of their 1.0.0 release.
From a code level, they're simply a request that doesn't return a value, so feel free to keep any existing code, but change command to request and comply to reply.
Commands do not add any functionality on top of events; instead, they provide a semantic distinction and enforce simpler logic.
setHandler; execute;
--
var commands = new Backbone.Wreqr.Commands();
commands.setHandler("foo", function(){
console.log("the foo command was executed");
});
commands.execute(“foo");
Requests the status of some object in app
Application.reqres – instance of Backbone.Wreqr.RequestResponse.
* The difference between Events and Requests is that Requests have intention. Requests are asking for a very specific thing to occur.
* The requests are 'one-to-one,' so you cannot have multiple 'listeners' to a single request
* Easy to misuse - like other global objects
--
_.extend(myView, Backbone.Radio.Requests);
---
var reqres = new Backbone.Wreqr.RequestResponse();
// Set up an object to reply to a request. In this case,
// whether or not its visible.
myObject.reply('visible', this.isVisible);
// Get whether it's visible or not.
var isViewVisible = myObject.request('visible');
Radio vs wreqr: channels
A Channel is simply an object that has Backbone.Events and Radio.Requests mixed into it: it's a standalone message bus comprised of both systems.