self.$table = $(QWeb.render("Interface", {}));
self.$element.append(self.$table);
self.header = new openerp.web.Header(self);
- self.header.on_logout.add(self.on_logout);
- self.header.on_action.add(self.on_menu_action);
+ self.header.on_logout.add(this.proxy('on_logout'));
+ self.header.on_action.add(this.proxy('on_menu_action'));
self.header.appendTo($("#oe_header"));
self.menu = new openerp.web.Menu(self, "oe_menu", "oe_secondary_menu");
- self.menu.on_action.add(self.on_menu_action);
+ self.menu.on_action.add(this.proxy('on_menu_action'));
self.menu.start();
},
show_common: function() {
}
}
}
+ },
+ /**
+ * Proxies a method of the object, in order to keep the right ``this`` on
+ * method invocations.
+ *
+ * This method is similar to ``Function.prototype.bind`` or ``_.bind``, and
+ * even more so to ``jQuery.proxy`` with a fundamental difference: its
+ * resolution of the method being called is lazy, meaning it will use the
+ * method as it is when the proxy is called, not when the proxy is created.
+ *
+ * Other methods will fix the bound method to what it is when creating the
+ * binding/proxy, which is fine in most javascript code but problematic in
+ * OpenERP Web where developers may want to replace existing callbacks with
+ * theirs.
+ *
+ * The semantics of this precisely replace closing over the method call.
+ *
+ * @param {String} method_name name of the method to invoke
+ * @returns {Function} proxied method
+ */
+ proxy: function (method_name) {
+ var self = this;
+ return function () {
+ return self[method_name].apply(self, arguments);
+ }
}
});
});
this.$element.find('.oe-list-add')
- .click(this.do_add_record)
+ .click(this.proxy('do_add_record'))
.attr('disabled', grouped && this.options.editable);
this.$element.find('.oe-list-delete')
.attr('disabled', true)
- .click(this.do_delete_selected);
+ .click(this.proxy('do_delete_selected'));
this.$element.find('thead').delegate('th.oe-sortable[data-id]', 'click', function (e) {
e.stopPropagation();
this.no_leaf = !!context['group_by_no_leaf'];
this.reload_view(!!group_by, context).then(
- $.proxy(this, 'reload_content'));
+ this.proxy('reload_content'));
},
/**
* Handles the signal to delete lines from the records list
$row.remove();
self.refresh_zebra(index);
},
- 'reset': $.proxy(this, 'on_records_reset'),
+ 'reset': function () { return self.on_records_reset(); },
'change': function (event, record) {
var $row = self.$current.find('[data-id=' + record.get('id') + ']');
$row.replaceWith(self.render_record(record));
});
},
render: function () {
+ var self = this;
if (this.$current) {
this.$current.remove();
}
this.$current = this.$_element.clone(true);
this.$current.empty().append(
QWeb.render('ListView.rows', _.extend({
- render_cell: $.proxy(this, 'render_cell')}, this)));
+ render_cell: function () { return self.render_cell(); }
+ }, this)));
this.pad_table_to(5);
},
pad_table_to: function (count) {
record: record,
row_parity: (index % 2 === 0) ? 'even' : 'odd',
view: this.view,
- render_cell: $.proxy(this, 'render_cell')
+ render_cell: function () { return this.render_cell(); }
});
},
/**
this.page = 0;
- this.records.bind('reset', $.proxy(this, 'on_records_reset'));
+ var self = this;
+ this.records.bind('reset', function () {
+ return self.on_records_reset(); });
},
make_fragment: function () {
return document.createDocumentFragment();
.delegate('button', 'keyup', function (e) {
e.stopImmediatePropagation();
})
- .keyup($.proxy(self, 'on_row_keyup'));
+ .keyup(function () { return self.on_row_keyup(); });
if (row) {
$new_row.replaceAll(row);
} else if (self.options.editable) {
this.render_row_as_form();
},
render_record: function (record) {
- var index = this.records.indexOf(record);
+ var index = this.records.indexOf(record),
+ self = this;
// FIXME: context dict should probably be extracted cleanly
return QWeb.render('ListView.row', {
columns: this.columns,
record: record,
row_parity: (index % 2 === 0) ? 'even' : 'odd',
view: this.view,
- render_cell: $.proxy(this, 'render_cell'),
+ render_cell: function () { return self.render_cell(); },
edited: !!this.edition_form
});
}