Odoo 网络客户端。无法 select 具有 jquery select 的 html 元素或

Odoo web client. Unable to select an html element with the jquery selector

以下参考Odoo v9企业版

任务:从主菜单 -> 时间表打开时间表表单时,在详细信息选项卡上发送 .click() 事件,以便详细信息选项卡打开。

问题:当我使用 selector 到 select 元素时,我在 return 中什么也得不到。 (我已经确认 select 或者我使用的是我感兴趣的 dom 元素的正确选择)

根据odoo web 客户端的官方文档,我扩展了web.FormView 小部件,并覆盖了它的启动方法。通过查看这些示例,在我看来,当 start 方法被调用时, DOM 已经被渲染了。

当我在 start 方法中使用 console.log(this) 时,我可以看到一个在 $el 变量中具有 DOM 的对象。

我正在尝试使用 jquery select 制作一个 selection,但是我无法获得我的对象。

我的自定义小部件 js:

odoo.define('t9397.form_override', function(require) {
    "use strict";
    var core = require('web.core');
    var web_widget = require('web.FormView')

    var FormWidgetOverride = web_widget.extend({

    start : function(record) {
        console.log('overridden')
        console.log(this)
        this.$("a[data-toggle='tab']:contains('Details')").click()
        $("a[data-toggle='tab']:contains('Details')").click()// trying both
        return this._super()

        }
    })
    core.view_registry.add('form', FormWidgetOverride);
});

我要向其发送点击事件的DOM对象:

< a data-toggle="tab" disable_anchor="true" role="tab" href="#notebook_page_22">Details< /a >

我对 promises,Jquery,尤其是 odoo 的网络客户端的了解相当有限。任何帮助将不胜感激。

start()可能会执行包括异步过程在内的渲染任务,所以需要等待它执行完毕。根据 documentation:

A widget is not guaranteed to work correctly until its start() method has finished executing. The widget's parent/creator must wait for a widget to be fully started before interacting with it.

通常,start 应该 return 一个 Deferred() jQuery object,如果 start() 本身在 super 中正确实现,那么您可以使用从它的调用接收到的 Deferred 对象等待它:

第一个使用简单代码的案例:

start : function() {
    var sup_ready = this._super();
    sup_ready.done(function(){
        //your code:
        console.log('overridden');
        console.log(this);
        this.$("a[data-toggle='tab']:contains('Details')").click();
        $("a[data-toggle='tab']:contains('Details')").click(); // trying both
    });
    return $.when( sup_ready );
    }
});

第二种情况,用于异步过程和更复杂的代码:

start : function() {
    var sup_ready = this._super();
    var me_ready = $.Deferred();
    . . .
    sup_ready.done(function(){
        . . .
        . . .
        //finally Resolve or Reject your deferred object:
        //Resovle:
        me_ready.resolve(); //use it if all go ok
        // *OR* Reject (in case something go wong) to indicate failure:
//      me_ready.reject();
    });
    . . . 
    return $.when( sup_ready, me_ready );
});

请注意,我将 me_ready.resolve() 放在 sup_ready.done() 中,但这不是绝对必要的,通常它可能是其他方式,即您可以拒绝或解决此 me_ready 之外的 sup_ready.done(),您可以在代码中的任何位置解析或拒绝 me_ready 延迟对象。

以上第二种情况不适用于你当前的问题,但这是一个以后要避免的陷阱,以防万一。

作为您选择的 start() 方式的 替代方法 ,还请考虑 events property 小部件并检查是否可以将其应用于您的案例...