8. Create and instanciate Widget
1. Define MyWidget
2. Instanciate it
odoo.define('new_widget', function(require)
{
var Widget = require('web.Widget');
var MyWidget = Widget.extend({
template: "my_template"
});
var x = new MyWidget();
x.appendTo($('#somewhere'));
});
Code: tiny.cc/async-5
9. Create and instanciate - Fix
1. Define MyWidget
2. Instanciate it in an action
odoo.define('new_widget', function (require) {
// require...
var MyWidget = Widget.extend({
template: "my_template"
});
var MyAction = AbstractAction.extend({
start: function () {
var myWidgetInstance = new MyWidget();
var prom = myWidgetInstance.appendTo ($('#somewhere'))
return Promise.all([
prom,
this._super.apply(this, arguments)
])
}
});
core.action_registry.add('my_action', MyAction);
});
Code: tiny.cc/async-6
11. 1. Define Widget
2. On click row showDetails
3. showDetails RPC then render
4. On click button (in detail)
navigateTo (in a modal)
odoo.define('master_detail_widget', function (require) {
// require ...
return Widget.extend({
template: 'master_detail_template',
events: {
'click tr': 'showDetails',
'click button.navigateTo': 'navigateTo'
},
async showDetails(ev) {
this.id = ev.target.dataset.id;
this.data = await this._rpc({/*...*/ id: this.id});
this.render();
},
navigateTo(ev) {
this.do_action('open_record_details',
{
recordId: this.id,
target: 'new'
});
}
});
});
The Code
Code: tiny.cc/async-7
12. What happens if a
user clicks on a
row, then
showDetails right
after?
odoo.define('master_detail_widget', function (require) {
// require ...
return Widget.extend({
template: 'master_detail_template',
events: {
'click tr': 'showDetails',
'click button.navigateTo': 'navigateTo'
},
async showDetails(ev) {
this.id = ev.target.dataset.id;
this.data = await this._rpc({/*...*/ id: this.id});
this.render();
},
navigateTo(ev) {
this.do_action('open_record_details',
{
recordId: this.id,
target: 'new'
});
}
});
});
Question
Code: tiny.cc/async-7
13. Issue: when the user clicks fast
on navigateTo just after
selecting a row, he is shown
with the details of the
previously selected row
Fix: set the id of the selected row
after the rpc
odoo.define('master_detail_widget', function (require) {
// require ...
return Widget.extend({
template: 'master_detail_template',
events: {
'click tr': 'showDetails',
'click button.navigateTo': 'navigateTo'
},
async showDetails(ev) {
var id = ev.target.dataset.id;
this.data = await this._rpc({/*...*/ id: id});
this.id = id;
this.render();
},
navigateTo() {
this.do_action('open_record_details',
{
recordId: this.id,
target: 'new'
});
}
});
});
[FIX] fast click
Code: tiny.cc/async-8
14. when the user clicks fast on
different rows
Issue 1: he has to wait a long time
to see the last one he
selected
Issue 2: the details do not always
arrive in order
Other issues
odoo.define('master_detail_widget', function (require) {
// require ...
return Widget.extend({
template: 'master_detail_template',
events: {
'click tr': 'showDetails',
'click button.navigateTo': 'navigateTo'
},
async showDetails(ev) {
var id = ev.target.dataset.id;
this.data = await this._rpc({/*...*/ id: id});
this.id = id;
this.render();
},
navigateTo() {
this.do_action('open_record_details',
{
recordId: this.id,
target: 'new'
});
}
});
});
odoo.define('master_detail_widget', function (require) {
// require ...
return Widget.extend({
template: 'master_detail_template',
events: {
'click tr': 'showDetails',
'click button.navigateTo': 'navigateTo'
},
async showDetails(ev) {
var id = ev.target.dataset.id;
this.data = await this._rpc({/*...*/ id: id});
this.id = id;
this.render();
},
navigateTo() {
this.do_action('open_record_details',
{
recordId: this.id,
target: 'new'
});
}
});
});
Code:
15. ● Show last ASAP
● Show all in sequence
You need to decide
20. More Odoo Primitives
/web/static/src/js/core/
concurrency.js
1. Do not execute if not ordered
2. Execute one after the other
3. Execute last as fast as possible
4. Execute first, last, wait for
completed
5. Wait X milliseconds
1. const dm = new DropMisordered();
dm.add(promise) Promise;
2. const m = new Mutex();
m.exec(function) Promise;
3. const dp = new DropPrevious();
dp.add(promise) Promise;
4. const mdp = new MutexedDropPrevious();
mdp.exec(function) Promise
5. delay(_ms) Promise
21. ● Know what returns a Promise
● Wait for promises
● Async is hard, use concurrency.js
primitives
To remember