use Binder to track and unbind listeners

This commit is contained in:
spalger 2015-10-23 13:06:23 -05:00
parent 37fc8d072e
commit d6d2355844
6 changed files with 26 additions and 25 deletions

View file

@ -1,6 +1,7 @@
var d3 = require('d3');
var _ = require('lodash');
var $ = require('jquery');
var Binder = require('ui/Binder');
var positionTooltip = require('./positionTooltip');
var allContents = [];
@ -28,6 +29,8 @@ function Tooltip(id, el, formatter, events) {
this.tooltipClass = 'vis-tooltip';
this.tooltipSizerClass = 'vis-tooltip-sizing-clone';
this.showCondition = _.constant(true);
this.binder = new Binder();
}
/**
@ -128,7 +131,7 @@ Tooltip.prototype.render = function () {
var $chart = self.$getChart();
if ($chart) {
$chart.on('mouseleave', function (event) {
self.binder.jqOn($chart, 'mouseleave', function (event) {
// only clear when we leave the chart, so that
// moving between points doesn't make it reposition
$chart.removeData('previousPlacement');
@ -159,7 +162,7 @@ Tooltip.prototype.render = function () {
}
}
fakeD3Bind(this, 'mousemove', function () {
this.binder.fakeD3Bind(this, 'mousemove', function () {
if (!self.showCondition.call(element, d, i)) {
return render();
}
@ -168,26 +171,16 @@ Tooltip.prototype.render = function () {
return render(self.formatter(events));
});
fakeD3Bind(this, 'mouseleave', function () {
this.binder.fakeD3Bind(this, 'mouseleave', function () {
render();
});
});
};
};
function fakeD3Bind(el, event, handler) {
$(el).on(event, function (e) {
// mimick https://github.com/mbostock/d3/blob/3abb00113662463e5c19eb87cd33f6d0ddc23bc0/src/selection/on.js#L87-L94
var o = d3.event; // Events can be reentrant (e.g., focus).
d3.event = e;
try {
handler.apply(this, [this.__data__]);
} finally {
d3.event = o;
}
});
}
Tooltip.prototype.destroy = function () {
this.binder.destroy();
};
module.exports = function TooltipFactoryProvider() {
return Tooltip;

View file

@ -20,7 +20,7 @@ define(function (require) {
this.data = data;
this.alertDefs = alertDefs || [];
$(vis.el).on('mouseenter', '.vis-alerts-tray', function () {
vis.binder.jqOn(vis.el, 'mouseenter', '.vis-alerts-tray', function () {
var $tray = $(this);
hide();
$(vis.el).on('mousemove', checkForExit);

View file

@ -3,6 +3,7 @@ define(function (require) {
var d3 = require('d3');
var _ = require('lodash');
var errors = require('ui/errors');
var Binder = require('ui/Binder');
var Data = Private(require('ui/vislib/lib/data'));
var Layout = Private(require('ui/vislib/lib/layout/layout'));
@ -43,7 +44,7 @@ define(function (require) {
}
this.layout = new Layout(vis.el, vis.data, vis._attr.type, opts);
this.binder = new Binder();
this.renderArray = _.filter([
this.layout,
this.legend,
@ -203,13 +204,12 @@ define(function (require) {
* @method destroy
*/
Handler.prototype.destroy = function () {
this.charts.forEach(function (chart) {
this.binder.destroy();
this.charts.splice(0).forEach(function (chart) {
if (_.isFunction(chart.destroy)) {
chart.destroy();
}
});
this.charts.length = 0;
};
return Handler;

View file

@ -3,6 +3,8 @@ define(function (require) {
var _ = require('lodash');
var d3 = require('d3');
var Binder = require('ui/Binder');
var ResizeChecker = Private(require('ui/vislib/lib/resize_checker'));
var Events = Private(require('ui/events'));
var handlerTypes = Private(require('ui/vislib/lib/handler/handler_types'));
@ -25,6 +27,7 @@ define(function (require) {
}
Vis.Super.apply(this, arguments);
this.el = $el.get ? $el.get(0) : $el;
this.binder = new Binder();
this.ChartClass = chartTypes[config.type];
this._attr = _.defaults({}, config || {}, {
legendOpen: true
@ -33,7 +36,7 @@ define(function (require) {
// bind the resize function so it can be used as an event handler
this.resize = _.bind(this.resize, this);
this.resizeChecker = new ResizeChecker(this.el);
this.resizeChecker.on('resize', this.resize);
this.binder.on(this.resizeChecker, 'resize', this.resize);
}
/**
@ -108,7 +111,7 @@ define(function (require) {
Vis.prototype.destroy = function () {
var selection = d3.select(this.el).select('.vis-wrapper');
this.resizeChecker.off('resize', this.resize);
this.binder.destroy();
this.resizeChecker.destroy();
if (this.handler) this._runOnHandler('destroy');

View file

@ -25,6 +25,7 @@ define(function (require) {
this.handler = handler;
this.chartEl = el;
this.chartData = chartData;
this.tooltips = [];
var events = this.events = new Dispatch(handler);
@ -34,6 +35,7 @@ define(function (require) {
// Add tooltip
this.tooltip = new Tooltip('chart', $el, formatter, events);
this.tooltips.push(this.tooltip);
}
this._attr = _.defaults(this.handler._attr || {}, {});
@ -83,7 +85,9 @@ define(function (require) {
Chart.prototype.destroy = function () {
var selection = d3.select(this.chartEl);
this.events.removeAllListeners();
if (this.tooltip) this.tooltip.hide();
this.tooltips.forEach(function (tooltip) {
tooltip.destroy();
});
selection.remove();
selection = null;
};

View file

@ -163,7 +163,8 @@ define(function (require) {
return touchdownTmpl(callPlay(d3.event));
}
var endzoneTT = this.endzoneTT = new Tooltip('endzones', this.handler.el, textFormatter, null);
var endzoneTT = new Tooltip('endzones', this.handler.el, textFormatter, null);
this.tooltips.push(endzoneTT);
endzoneTT.order = 0;
endzoneTT.showCondition = function inEndzone() {
return callPlay(d3.event).touchdown;