diff --git a/addons/calendar/static/src/views/fields/many2many_attendee.js b/addons/calendar/static/src/views/fields/many2many_attendee.js index e1c6a474b01..095d9410577 100644 --- a/addons/calendar/static/src/views/fields/many2many_attendee.js +++ b/addons/calendar/static/src/views/fields/many2many_attendee.js @@ -11,7 +11,7 @@ export class Many2ManyAttendee extends Many2ManyTagsAvatarField { setup() { super.setup(); this.specialData = useSpecialData((orm, props) => { - const { context, name, record } = this.props; + const { context, name, record } = props; return orm.call( "res.partner", "get_attendee_detail", diff --git a/addons/web/static/src/model/relational_model/utils.js b/addons/web/static/src/model/relational_model/utils.js index 9ff071e6f4a..2e7608b48b4 100644 --- a/addons/web/static/src/model/relational_model/utils.js +++ b/addons/web/static/src/model/relational_model/utils.js @@ -614,7 +614,7 @@ export function useRecordObserver(callback) { async (record) => { if (firstCall) { firstCall = false; - await callback(record); + await callback(record, props); def.resolve(); } else { return batched( @@ -624,7 +624,7 @@ export function useRecordObserver(callback) { // We must do it manually. return; } - await callback(record); + await callback(record, props); def.resolve(); }, () => new Promise((resolve) => window.requestAnimationFrame(resolve)) diff --git a/addons/web/static/src/views/fields/relational_utils.js b/addons/web/static/src/views/fields/relational_utils.js index 310919c8b4c..629cbfca16d 100644 --- a/addons/web/static/src/views/fields/relational_utils.js +++ b/addons/web/static/src/views/fields/relational_utils.js @@ -18,7 +18,7 @@ import { createElement, parseXML } from "@web/core/utils/xml"; import { FormArchParser } from "@web/views/form/form_arch_parser"; import { loadSubViews } from "@web/views/form/form_controller"; import { FormRenderer } from "@web/views/form/form_renderer"; -import { extractFieldsFromArchInfo } from "@web/model/relational_model/utils"; +import { extractFieldsFromArchInfo, useRecordObserver } from "@web/model/relational_model/utils"; import { computeViewClassName, isNull } from "@web/views/utils"; import { ViewButton } from "@web/views/view_button/view_button"; import { useViewButtons } from "@web/views/view_button/view_button_hook"; @@ -39,11 +39,11 @@ import { SelectCreateDialog } from "@web/views/view_dialogs/select_create_dialog import { Component, - onWillStart, onWillUpdateProps, useComponent, useEffect, useEnv, + useState, useSubEnv, } from "@odoo/owl"; @@ -156,12 +156,15 @@ export function useSpecialData(loadFn) { } ormWithCache.call = (...args) => specialDataCaches[key].read(...args); - const result = {}; - onWillStart(async () => { - result.data = await loadFn(ormWithCache, component.props); + const result = useState({}); + useRecordObserver(async (record, props) => { + result.data = await loadFn(ormWithCache, { ...props, record }); }); onWillUpdateProps(async (props) => { - result.data = await loadFn(ormWithCache, props); + // useRecordObserver callback is not called when the record doesn't change + if (props.record.id === component.props.record.id) { + result.data = await loadFn(ormWithCache, props); + } }); return result; } diff --git a/addons/web/static/tests/views/fields/statusbar_field_tests.js b/addons/web/static/tests/views/fields/statusbar_field_tests.js index 2dc24e62d61..d936675e61c 100644 --- a/addons/web/static/tests/views/fields/statusbar_field_tests.js +++ b/addons/web/static/tests/views/fields/statusbar_field_tests.js @@ -407,6 +407,7 @@ QUnit.module("Fields", (hooks) => { ".o_statusbar_status button:not(.dropdown-toggle)" ); await click(buttons[buttons.length - 1]); + await nextTick(); assert.containsN(target, ".o_statusbar_status button:not(.dropdown-toggle)", 2); } ); diff --git a/addons/web/static/tests/views/form/form_view_tests.js b/addons/web/static/tests/views/form/form_view_tests.js index 045738aa365..cef6015a822 100644 --- a/addons/web/static/tests/views/form/form_view_tests.js +++ b/addons/web/static/tests/views/form/form_view_tests.js @@ -54,6 +54,7 @@ import { CharField } from "@web/views/fields/char/char_field"; import { DateTimeField } from "@web/views/fields/datetime/datetime_field"; import { Field } from "@web/views/fields/field"; import { IntegerField } from "@web/views/fields/integer/integer_field"; +import { useSpecialData } from "@web/views/fields/relational_utils"; import { X2ManyField, x2ManyField } from "@web/views/fields/x2many/x2many_field"; import { FormController } from "@web/views/form/form_controller"; import { companyService } from "@web/webclient/company_service"; @@ -14262,4 +14263,39 @@ QUnit.module("Views", (hooks) => { }); assert.strictEqual(target.querySelector(".o_breadcrumb").innerText, "Unnamed"); }); + + QUnit.test("field with special data", async function (assert) { + class MyWidget extends Component { + static template = xml`