Odoo16 OWL组件页面状态存储与回退恢复方案咨询
解决Odoo ir.actions.client组件页面状态保存与恢复问题
方法一:使用浏览器本地存储(sessionStorage/localStorage)
在组件状态变更时将参数、结果存入本地存储,初始化时读取并恢复状态,是最直接的前端临时存储方案。
修改组件代码的关键逻辑如下:
class TestComponent extends Component { static template = xml` <input t-model="params_test" t-on-change="saveState"> <t foreach="results" t-as="val" t-key="val"> <t t-esc="val"/> </t> `; setup() { // 初始化时从sessionStorage恢复状态 const savedParams = sessionStorage.getItem('test_component_params'); const savedResults = sessionStorage.getItem('test_component_results'); this.params_test = useState(savedParams ? savedParams : ""); this.results = useState(savedResults ? JSON.parse(savedResults) : []); // 监听状态变化,自动同步到存储 watch(() => [this.params_test, this.results], ([newParams, newResults]) => { sessionStorage.setItem('test_component_params', newParams); sessionStorage.setItem('test_component_results', JSON.stringify(newResults)); }, { deep: true }); } dosomething(){ // 原有数据获取逻辑,更新results后watch会自动触发保存 // ... } // 可选:组件销毁时清理存储(不需要跨会话保留时启用) willUnmount() { // sessionStorage.removeItem('test_component_params'); // sessionStorage.removeItem('test_component_results'); } } TestComponent.template = "test_template"; registry.category("actions").add("testcomponent", TestComponent);
- 用
sessionStorage:仅当前浏览器会话有效,关闭标签页自动清除,适合临时状态保存;如需跨会话保留,替换为localStorage。 - 通过
watch监听状态变更,自动完成存储同步,无需手动调用保存方法。
方法二:利用Odoo路由/Action上下文传递状态
如果是通过Odoo内置Action跳转其他页面,可以将当前组件状态附加到跳转Action的上下文,返回时从上下文读取恢复。
- 跳转时传递状态:
// 点击记录跳转的逻辑 goToRecord(recordId) { const actionContext = { default_test_params: this.params_test, default_test_results: this.results, }; // 调用Odoo Action跳转,附带状态上下文 this.env.services.action.doAction({ type: 'ir.actions.act_window', res_model: 'other.model', res_id: recordId, views: [[false, 'form']], context: actionContext, }); }
- 组件初始化时读取上下文恢复状态:
setup() { const context = this.env.context; this.params_test = useState(context.default_test_params || ""); this.results = useState(context.default_test_results || []); // 其他初始化逻辑 }
- 该方案依赖Odoo的Action上下文机制,状态不会暴露到浏览器存储,适合纯Odoo内部跳转场景。
方法三:服务器端用户会话存储
如果需要状态跨设备/浏览器会话同步,可以将状态保存到Odoo的用户会话中。
- 后端新增RPC方法:
from odoo import http, models class ResUsers(models.Model): _inherit = 'res.users' def save_test_component_state(self, params, results): session = self.env['ir.session'].sudo().search([('session_id', '=', http.request.session.sid)], limit=1) if session: session.write({ 'test_component_state': { 'params': params, 'results': results, } }) def get_test_component_state(self): session = self.env['ir.session'].sudo().search([('session_id', '=', http.request.session.sid)], limit=1) return session.test_component_state or {}
- 前端调用RPC保存/读取状态:
setup() { // 初始化时从后端拉取状态 this.env.services.rpc('/web/dataset/call_kw/res.users/get_test_component_state', { model: 'res.users', method: 'get_test_component_state', args: [], kwargs: {}, }).then(state => { this.params_test = useState(state.params || ""); this.results = useState(state.results || []); }); // 状态变化时同步到后端 watch(() => [this.params_test, this.results], ([newParams, newResults]) => { this.env.services.rpc('/web/dataset/call_kw/res.users/save_test_component_state', { model: 'res.users', method: 'save_test_component_state', args: [newParams, newResults], kwargs: {}, }); }, { deep: true }); }
- 状态存储在服务器端,适合跨设备同步需求,但会增加服务器存储开销。
内容的提问来源于stack exchange,提问作者Grant.S
相关产品推荐
相关产品推荐

