diff --git a/addons/base/static/src/js/list.js b/addons/base/static/src/js/list.js index 996822c4a21..642a0743e9a 100644 --- a/addons/base/static/src/js/list.js +++ b/addons/base/static/src/js/list.js @@ -629,19 +629,24 @@ openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base. this.dataset = opts.dataset; this.records = opts.records; - this.records.bind('remove', function (event, record) { - var $row = self.$current.find('[data-id=' + record.get('id') + ']'); - var index = $row.data('index'); - $row.nextAll().each(function (row) { - $(row).data('index', index++); - }); - $row.remove(); - }); - this.records.bind('reset', $.proxy(this, 'on_records_reset')); - this.records.bind('change', function (event, record) { - var $row = self.$current.find('[data-id=' + record.get('id') + ']'); - $row.replaceWith(self.render_record($row.data('index'))); - }); + this.record_callbacks = { + 'remove': function (event, record) { + var $row = self.$current.find('[data-id=' + record.get('id') + ']'); + var index = $row.data('index'); + $row.nextAll().each(function (row) { + $(row).data('index', index++); + }); + $row.remove(); + }, + 'reset': $.proxy(this, 'on_records_reset'), + 'change': function (event, record) { + var $row = self.$current.find('[data-id=' + record.get('id') + ']'); + $row.replaceWith(self.render_record($row.data('index'))); + } + }; + _(this.record_callbacks).each(function (callback, event) { + this.records.bind(event, callback); + }, this); this.$_element = $('') .appendTo(document.body) @@ -729,7 +734,10 @@ openerp.base.ListView.List = openerp.base.Class.extend( /** @lends openerp.base. /** * Death signal, cleans up list display */ - on_records_reset: function (ev, records) { + on_records_reset: function () { + _(this.record_callbacks).each(function (callback, event) { + this.records.unbind(event, callback); + }, this); if (!this.$current) { return; } this.$current.remove(); this.$current = null; @@ -1127,7 +1135,7 @@ openerp.base.ListView.Groups = openerp.base.Class.extend( /** @lends openerp.bas .map(function (child) { return child.get_records(); }).flatten().value(); - }, + } }); /** @@ -1150,6 +1158,24 @@ var Events = { } return this; }, + /** + * @param {String} event event to unbind on the current object + * @param {function} [handler] specific event handler to remove (otherwise unbind all handlers for the event) + * @returns this + */ + unbind: function (event, handler) { + var calls = this._callbacks || {}; + if (!(event in calls)) { return this; } + if (!handler) { + delete calls[event]; + } else { + var handlers = calls[event]; + handlers.splice( + _(handlers).indexOf(handler), + 1); + } + return this; + }, /** * @param {String} event * @returns this diff --git a/addons/base/static/test/list-utils.js b/addons/base/static/test/list-utils.js index ffdc3b66b49..0b15b81f544 100644 --- a/addons/base/static/test/list-utils.js +++ b/addons/base/static/test/list-utils.js @@ -65,6 +65,28 @@ $(document).ready(function () { ok(triggered); }); + test('Unbind all handlers', function () { + var e = create(openerp.base.list.Events), passed = 0; + e.bind('foo', function () { passed++; }); + e.trigger('foo'); + strictEqual(passed, 1); + e.unbind('foo'); + e.trigger('foo'); + strictEqual(passed, 1); + }); + test('Unbind one handler', function () { + var e = create(openerp.base.list.Events), p1 = 0, p2 = 0, + h1 = function () { p1++; }, h2 = function () { p2++; }; + e.bind('foo', h1); + e.bind('foo', h2); + e.trigger('foo'); + strictEqual(p1, 1); + strictEqual(p2, 1); + e.unbind('foo', h1); + e.trigger('foo'); + strictEqual(p1, 1); + strictEqual(p2, 2); + }); module('list-records', { setup: function () {