diff --git a/addons/web/static/src/model/record.js b/addons/web/static/src/model/record.js
index d12623dd286..302de461d84 100644
--- a/addons/web/static/src/model/record.js
+++ b/addons/web/static/src/model/record.js
@@ -12,10 +12,9 @@ class StandaloneRelationalModel extends RelationalModel {
load(params = {}) {
if (params.values) {
const data = params.values;
- if (params.mode) {
- this.config.mode = params.mode;
- }
- this.root = this._createRoot(this.config, data);
+ const config = this._getNextConfig(this.config, params);
+ this.root = this._createRoot(config, data);
+ this.config = config;
return;
}
return super.load(params);
@@ -50,7 +49,7 @@ class _Record extends Component {
modelServices.orm = this.orm;
this.model = useState(new StandaloneRelationalModel(this.env, modelParams, modelServices));
- const loadWithValues = async (values) => {
+ const prepareLoadWithValues = async (values) => {
values = pick(values, ...Object.keys(modelParams.config.activeFields));
const proms = [];
for (const fieldName in values) {
@@ -113,20 +112,26 @@ class _Record extends Component {
}
await Promise.all(proms);
}
- return this.model.load({ values });
+ return values;
};
- onWillStart(() => {
+ onWillStart(async () => {
if (this.props.values) {
- return loadWithValues(this.props.values);
+ const values = await prepareLoadWithValues(this.props.values);
+ return this.model.load({ values });
} else {
return this.model.load();
}
});
- onWillUpdateProps((nextProps) => {
+ onWillUpdateProps(async (nextProps) => {
+ const params = {};
+ if (nextProps.info.resId !== this.model.root.resId) {
+ params.resId = nextProps.info.resId;
+ }
if (nextProps.values) {
- return loadWithValues(nextProps.values);
- } else if (nextProps.info.resId !== this.model.root.resId) {
- return this.model.load({ resId: nextProps.info.resId });
+ params.values = await prepareLoadWithValues(nextProps.values);
+ }
+ if (Object.keys(params).length) {
+ return this.model.load(params);
}
});
}
diff --git a/addons/web/static/tests/views/record_tests.js b/addons/web/static/tests/views/record_tests.js
index 450182da35e..1bd0cf95481 100644
--- a/addons/web/static/tests/views/record_tests.js
+++ b/addons/web/static/tests/views/record_tests.js
@@ -607,4 +607,72 @@ QUnit.module("Record Component", (hooks) => {
assert.strictEqual(increment.textContent, "2");
assert.strictEqual(field.textContent, "blop");
});
+
+ QUnit.test("can switch records with values", async (assert) => {
+ class Parent extends Component {
+ setup() {
+ this.fields = {
+ foo: {
+ name: "foo",
+ type: "char",
+ },
+ bar: {
+ name: "bar",
+ type: "boolean",
+ },
+ };
+ this.values = {
+ foo: "abc",
+ bar: true,
+ };
+ this.state = useState({ currentId: 99 });
+ }
+
+ next() {
+ this.state.currentId = 100;
+ this.values = {
+ foo: "def",
+ bar: false,
+ };
+ }
+ }
+ Parent.components = { Record, Field };
+ Parent.template = xml`
+ NEXT
+
+
+
+ `;
+ let _record;
+ patchWithCleanup(Record.components._Record.prototype, {
+ setup() {
+ super.setup();
+ _record = this;
+ },
+ });
+
+ await mount(Parent, target, {
+ env: await makeTestEnv({
+ serverData,
+ mockRPC(route) {
+ assert.step(route);
+ },
+ }),
+ });
+ // No load since the values are provided to the record
+ assert.verifySteps([]);
+ const field = target.querySelector("div[name='foo']");
+ // First values are loaded
+ assert.strictEqual(field.textContent, "abc");
+ // Verify that the underlying _Record Model root has the specified resId
+ assert.strictEqual(_record.model.root.resId, 99);
+
+ await click(target.querySelector("#next"));
+ // Still no load.
+ assert.verifySteps([]);
+ // Second values are loaded
+ assert.strictEqual(field.textContent, "def");
+ // Verify that the underlying _Record Model root has the updated resId
+ assert.strictEqual(_record.model.root.resId, 100);
+ });
});