In the previous article, I introduced you to your learning experience of passing values between Views in Backbone. This article focuses on introducing three ways of communication between Backbone Views.
The most critical section to master an MVC framework is to master how to communicate between various views. When I used Angular before, I thought that event-based communication methods ($on, $emit, $boardcast) or service-based methods were very useful. After moving to Backbone, due to insufficient understanding of Backbone's event mechanism and very flexible use, a good communication method has not been found. Until I saw this article, the author used a simple example to explain the three ways of communication between Backbone Views clearly. The translation is as follows:
The web page I am developing has two main parts, namely document and sidebar.
As shown in the above picture, I set up three views:
ApplicationView - Contains the lower view as the outermost view
DocumentView - Shows the content being edited or browsed
SidebarView - Show some document-related information
DocumentView and SidebarView are subviews of ApplicationView, so the overall view structure is shown in the figure below:
The user operates in any subview, and the other subview needs to be changed accordingly. But since the two child views cannot directly notify the other party (that is, their scopes are not directly related, unlike the parent view, which can contain the scopes of all its child views), I need an event mechanism.
After I Googled and referring to other people's methods, I summarized the following three different ways of communication.
1. Pass events through parent view
I pass events for its two child views through the parent view ( ApplicationView ). Because the parent view contains the scope of all its child views, it is best to use it as a medium for event delivery.
The JavaScript code is as follows:
var ApplicationView = Backbone.View.extend({initialize : function(){this.documentView = new DocumentView({parent:this});this.sidebarView = new SidebarView({parent:this});this.documentView.on('edit', this.documentEdited, this);},documentEdited : function(){// do some stuffthis.sidebarView.trigger('documentEdit');}});var DocumentView = Backbone.View.extend({onEdit : function(){this.trigger('edit');}});var SidebarView = Backbone.View.extend({initialize : function(){this.on('documentEdit', this.onDocumentEdit, this);},onDocumentEdit : function(){// react to document edit.}});However, this method is not efficient. Because I need to add an extra event handler to the ApplicationView documentEdited() . If a bunch of events are passed in the child view, the event handler function will be continuously triggered in the parent view, causing it to be overwhelmed.
Then let’s take a look at the second method.
2. Communication between views through EventBus
I create a global object EventBus by inheriting Backbone.Events . Inject it into each subview to broadcast events.
The JavaScript code is as follows:
var ApplicationView = Backbone.View.extend({initialize : function(){this.eventBus = _.extend({}, Backbone.Events); this.documentView = new DocumentView({eventBus: this.eventBus}); this.sidebarView = new SidebarView({eventBus: this.eventBus});},});var DocumentView = Backbone.View.extend({initialize : function(options){this.eventBus = options.eventBus;},onEdit : function(){this.eventBus.trigger('documentEdit');}});var SidebarView = Backbone.View.extend({initialize : function(options){this.eventBus = options.eventBus;this.eventBus.on('documentEdit', this.onDocumentEdit, this);},onDocumentEdit : function(){// react to document edit.}});In this method, I use EventBus as a global object to register events. If I want to communicate between views, I just need to inject EventBus into the view and I can easily trigger or listen for events through it.
Note: If you do not want to create global objects, you can still create EventBus at the module or view level for communication.
This method is already significantly better than the first method. However, we need to manually introduce EventBus in the subview, which shows that there is still room for improvement. So let’s take a look at the third method.
3. Use Backbone directly as the event registration machine
In the second method, I create a separate EventBus inherited from Backbone.Events . But recently I realized that the Backbone object itself is an object that mixes Events, so I directly use Backbone to broadcast events, so I don’t need to create another EventBus.
And the Backbone object can be called directly so I don't have to manually inject it in each subview.
The JavaScript code is as follows:
var ApplicationView = Backbone.View.extend({initialize : function(){this.documentView = new DocumentView();this.sidebarView = new SidebarView();},});var DocumentView = Backbone.View.extend({onEdit : function(){Backbone.trigger('documentEdit');}});var SidebarView = Backbone.View.extend({initialize : function(options){Backbone.on('documentEdit', this.onDocumentEdit, this);},onDocumentEdit : function(){// react to document edit.}});Summarize
I ended up using the third method in my project. And in my opinion, although it directly relies on the global Backbone object, it is extremely concise to use.