You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			132 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
			
		
		
	
	
			132 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
| (function () {
 | |
|   // Note: this is all the code required to customize Backbone's trigger() method to make
 | |
|   //   it resilient to exceptions thrown by event handlers. Indentation and code styles
 | |
|   //   were kept inline with the Backbone implementation for easier diffs.
 | |
| 
 | |
|   // The changes are:
 | |
|   //   1. added 'name' parameter to triggerEvents to give it access to the current event name
 | |
|   //   2. added try/catch handlers to triggerEvents with error logging inside every while loop
 | |
| 
 | |
|   // And of course, we update the protoypes of Backbone.Model/Backbone.View as well as
 | |
|   //   Backbone.Events itself
 | |
| 
 | |
|   // jscs:disable
 | |
| 
 | |
|   var arr = [];
 | |
| 
 | |
|   var slice = arr.slice;
 | |
| 
 | |
|   // Regular expression used to split event strings.
 | |
|   var eventSplitter = /\s+/;
 | |
| 
 | |
|   // Implement fancy features of the Events API such as multiple event
 | |
|   // names `"change blur"` and jQuery-style event maps `{change: action}`
 | |
|   // in terms of the existing API.
 | |
|   var eventsApi = function(obj, action, name, rest) {
 | |
|     if (!name) return true;
 | |
| 
 | |
|     // Handle event maps.
 | |
|     if (typeof name === 'object') {
 | |
|       for (var key in name) {
 | |
|         obj[action].apply(obj, [key, name[key]].concat(rest));
 | |
|       }
 | |
|       return false;
 | |
|     }
 | |
| 
 | |
|     // Handle space separated event names.
 | |
|     if (eventSplitter.test(name)) {
 | |
|       var names = name.split(eventSplitter);
 | |
|       for (var i = 0, l = names.length; i < l; i++) {
 | |
|         obj[action].apply(obj, [names[i]].concat(rest));
 | |
|       }
 | |
|       return false;
 | |
|     }
 | |
| 
 | |
|     return true;
 | |
|   };
 | |
| 
 | |
|   // A difficult-to-believe, but optimized internal dispatch function for
 | |
|   // triggering events. Tries to keep the usual cases speedy (most internal
 | |
|   // Backbone events have 3 arguments).
 | |
|   var triggerEvents = function(events, name, args) {
 | |
|     var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
 | |
|     var logError = function(error) {
 | |
|       console.log('Model caught error triggering', name, 'event:', error && error.stack ? error.stack : error);
 | |
|     };
 | |
|     switch (args.length) {
 | |
|       case 0:
 | |
|         while (++i < l) {
 | |
|           try {
 | |
|             (ev = events[i]).callback.call(ev.ctx);
 | |
|           }
 | |
|           catch (error) {
 | |
|             logError(error);
 | |
|           }
 | |
|         }
 | |
|         return;
 | |
|       case 1:
 | |
|         while (++i < l) {
 | |
|           try {
 | |
|             (ev = events[i]).callback.call(ev.ctx, a1);
 | |
|           }
 | |
|           catch (error) {
 | |
|             logError(error);
 | |
|           }
 | |
|         }
 | |
|         return;
 | |
|       case 2:
 | |
|         while (++i < l) {
 | |
|           try {
 | |
|             (ev = events[i]).callback.call(ev.ctx, a1, a2);
 | |
|           }
 | |
|           catch (error) {
 | |
|             logError(error);
 | |
|           }
 | |
|         }
 | |
|         return;
 | |
|       case 3:
 | |
|         while (++i < l) {
 | |
|           try {
 | |
|             (ev = events[i]).callback.call(ev.ctx, a1, a2, a3);
 | |
|           }
 | |
|           catch (error) {
 | |
|             logError(error);
 | |
|           }
 | |
|         }
 | |
|         return;
 | |
|       default:
 | |
|         while (++i < l) {
 | |
|           try {
 | |
|             (ev = events[i]).callback.apply(ev.ctx, args);
 | |
|           }
 | |
|           catch (error) {
 | |
|             logError(error);
 | |
|           }
 | |
|         }
 | |
|         return;
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   // Trigger one or many events, firing all bound callbacks. Callbacks are
 | |
|   // passed the same arguments as `trigger` is, apart from the event name
 | |
|   // (unless you're listening on `"all"`, which will cause your callback to
 | |
|   // receive the true name of the event as the first argument).
 | |
|   function trigger(name) {
 | |
|     if (!this._events) return this;
 | |
|     var args = slice.call(arguments, 1);
 | |
|     if (!eventsApi(this, 'trigger', name, args)) return this;
 | |
|     var events = this._events[name];
 | |
|     var allEvents = this._events.all;
 | |
|     if (events) triggerEvents(events, name, args);
 | |
|     if (allEvents) triggerEvents(allEvents, name, arguments);
 | |
|     return this;
 | |
|   }
 | |
| 
 | |
|   Backbone.Model.prototype.trigger
 | |
|     = Backbone.View.prototype.trigger
 | |
|     = Backbone.Collection.prototype.trigger
 | |
|     = Backbone.Events.trigger
 | |
|     = trigger;
 | |
| })();
 | |
| 
 |