Passing data from one Backbone view to another
backbone.js, javascript, jquery
Solution
Basicly you should use Backbone.Event:(Or it's equivalents in Marionette)
//Declaration
var notificationService = {};
_.extend(notificationService, Backbone.Events);
//Used by listener
notificationService.on("alert", function(o) {
alert(o);
});
//Used by publisher
notificationService.trigger("alert", {foo:"bar"});
The real question is how does it get passed from one view to another?
The way I see it, you have 2 options:
- Bubble notificationService from one view to another in initialization
- Wrap the notificationService with a requirejs model that returns it (creates a 'almost global' notificationService that can be passed by requirejs).
Although I don't like singletons a bit, this case a of a singleton notificationService object that can easily get injected by requirejs in every model will come in handy.
EDIT:
Another option, the quick and dirty one, just use jquery to trigger event on the DOM (specifically the body element) and listen to body in the other view
//on Listening view, after DOM is ready
$( "body" ).on( "alert", function( event, param1, param2 ) {
alert( param1 + "\n" + param2 );
});
//on Triggering view, after DOM is ready
$( "body").trigger( "alert", [ "Custom", "Event" ] );
NOTE:
notice that once a listening view is closed, it must removes itself from listening to events (unbind/off), so you wont have memory leak
Problem
Lets say I have the following Backbone view which loads two links, one with the anchor text "test1" and the other with the anchor text "test2". I bind a click event and I get the HTML of the link that was clicked and store it inside the clickedHtml variable. Now, this view is loaded by a Backbone router. When the user clicks either one of the two links (test1 or test2) another view called "main" will be loaded by the router. Now, how can I pass the "clickedHtml" variable to that view? Should I use LocalStorage? Should I declare it globally like window.clickedHtml? Is there a better way? Ty! ``` // file: views/test.js define([ 'jquery', 'underscore', 'backbone' ], function($, _, Backbone) { var Test = Backbone.View.extend({ el : '.test', initialize : function () { var that = this; that.$el.html('<a href="#/main">test1</a><br /><a href="#/main">test2</a>'); }, events : { 'click .test a' : 'click' }, click : function (e) { var clickedHtml = $(e.target).html(); } return Test; }); ``` Here is my router: ``` // file: router.js define([ 'jquery', 'underscore', 'backbone', 'views/test', 'views/main' ], function ($, _, Backbone, Test, Main) { var Router = Backbone.Router.extend({ routes: { '' : 'home', 'test' : 'test' } }); var initialize = function () { var router = new Router(); router.on('route:home', function () { var main = new Main(); }); router.on('route:test', function () { var test = new Test(); }); Backbone.history.start(); } return { initialize : initialize } }); ```