zoukankan      html  css  js  c++  java
  • odoo官方文档第十一章 Javascript Cheatsheet

    Javascript Cheatsheet

    有许多方法可以解决JavaScript和Odoo中的问题。 但是,Odoo框架被设计为可扩展(这是一个非常大的约束),并且一些常见问题有一个很好的标准解决方案。 标准解决方案可能具有易于理解的odoo开发人员的优势,并且可能会在修改Odoo时继续工作。

    本文档试图解释解决其中一些问题的方法。 请注意,这不是参考。 这只是一个随机的菜单集合,或者在某些情况下如何处理的解释。

    首先,请记住,使用JS自定义odoo的第一条规则是:尝试在python中执行此操作。 这可能看起来很奇怪,但是python框架是可扩展的,并且可以通过轻触xml或python来完成许多行为。 与使用JS相比,这通常具有更低的维护成本:

    如果需要与服务器通信并与javascript框架正确集成,则实现自定义行为通常更加困难。 自定义代码需要复制的框架有许多小细节。 例如,响应,或更新URL,或显示数据而不闪烁。

    本文档并未真正解释任何概念。 这更像是一本食谱(cookbook)。 有关更多详细信息,请参阅javascript参考页面(请参阅Javascript参考)

    Creating a new field widget

    这可能是一个非常常见的用例:我们希望以非常具体(可能依赖于业务)的方式在表单视图中显示一些信息。 例如,假设我们要根据某些业务条件更改文本颜色。

    这可以通过三个步骤完成:

    1. 创建新窗口小部件 widget,
    2. 在字段注册表中注册它,
    3. 然后将窗口小部件 widget添加到窗体视图中的字段
    • creating a new widget(创建新窗口小部件)
      这可以通过扩展小部件来完成:
    var FieldChar = require('web.basic_fields').FieldChar;
    
    var CustomFieldChar = Fieldchar.extend({
        renderReadonly: function () {
            // implement some custom logic here
        },
    });
    
    • registering it in the field registry(在字段注册表中注册它)
      Web客户端需要知道窗口小部件名称与其实际类之间的映射。 这是由注册表完成的:(add进行注册)
    var fieldRegistry = require('web.field_registry');
    
    fieldRegistry.add('my-custom-field', CustomFieldChar);
    
    • adding the widget in the form view(将窗口小部件 添加到窗体视图中的字段)
    <field name="somefield" widget="my-custom-field"/>
    

    请注意,只有表单,列表和看板视图使用此字段小部件注册表。 这些视图紧密集成,因为列表和看板视图可以显示在表单视图中。

    Modifying an existing field widget

    另一个用例是我们想要修改现有的字段小部件。 例如,odoo中的voip插件需要修改FieldPhone小部件,以增加在voip上轻松调用给定数字的可能性。 这是通过包含FieldPhone小部件来完成的,因此无需更改任何现有的表单视图。

    Field Widgets(AbstractField的(子类)的实例)与其他所有小部件一样,因此它们可以进行猴子补丁。 这看起来像这样:

    var basic_fields = require('web.basic_fields');
    var Phone = basic_fields.FieldPhone;
    
    Phone.include({
        events: _.extend({}, Phone.prototype.events, {
            'click': '_onClick',
        }),
    
        _onClick: function (e) {
            if (this.mode === 'readonly') {
                e.preventDefault();
                var phoneNumber = this.value;
                // call the number on voip...
            }
        },
    });
    

    请注意,无需将小部件添加到注册表,因为它已经注册。

    Modifying a main widget from the interface(从界面修改主窗口小部件)

    另一个常见用例是需要从用户界面自定义一些元素。 例如,在主菜单中添加消息。 在这种情况下,通常的过程是再次包含小部件。 这是唯一的方法,因为这些小部件没有注册表。

    这通常使用如下代码完成:

    var AppSwitcher = require('web_enterprise.AppSwitcher');
    
    AppSwitcher.include({
        render: function () {
            this._super();
            // do something else here...
        },
    });
    

    Adding a client action

    客户端操作是一个小部件,它将控制菜单栏下方的屏幕部分。 如有必要,它可以有一个控制面板。 定义客户端操作可以分两步完成:实现新窗口小部件,并在操作注册表中注册窗口小部件。

    • Implementing a new client action:
      这是通过创建一个小部件来完成的:
    var ControlPanelMixin = require('web.ControlPanelMixin');
    var Widget = require('web.Widget');
    
    var ClientAction = Widget.extend(ControlPanelMixin, {
        ...
    });
    

    如果您不需要,请不要添加控制面板mixin。 请注意,需要一些代码才能与控制面板交互(通过mixin给出的update_control_panel方法)。

    • Registering the client action:
      像往常一样,我们需要让Web客户端知道客户端操作和实际类之间的映射:
    var core = require('web.core');
    
    core.action_registry.add('my-custom-action', ClientAction);
    

    然后,要在Web客户端中使用客户端操作,我们需要使用正确的tag属性创建客户端操作记录(模型ir.actions.client的记录):

    <record id="my_client_action" model="ir.actions.client">
        <field name="name">Some Name</field>
        <field name="tag">my-custom-action</field>
    </record>
    

    Creating a new view (from scratch)

    创建新视图是一个更高级的主题。 这个备忘单(cheatsheet) 只会突出显示可能需要完成的步骤(无特定顺序):

    • 将新视图类型添加到ir.ui.view的字段类型:
    class View(models.Model):
        _inherit = 'ir.ui.view'
    
        type = fields.Selection(selection_add=[('map', "Map")])
    
    • 将新视图类型添加到ir.actions.act_window.view的字段view_mode
    class ActWindowView(models.Model):
        _inherit = 'ir.actions.act_window.view'
    
        view_mode = fields.Selection(selection_add=[('map', "Map")])
    
    • creating the four main pieces which makes a view (in JavaScript):
      我们需要一个视图(AbstractView的子类,这是工厂),一个渲染器(来自AbstractRenderer),一个控制器(来自AbstractController)和一个模型(来自AbstractModel)。 我建议首先简单地扩展超类:
    var AbstractController = require('web.AbstractController');
    var AbstractModel = require('web.AbstractModel');
    var AbstractRenderer = require('web.AbstractRenderer');
    var AbstractView = require('web.AbstractView');
    
    var MapController = AbstractController.extend({});
    var MapRenderer = AbstractRenderer.extend({});
    var MapModel = AbstractModel.extend({});
    
    var MapView = AbstractView.extend({
        config: {
            Model: MapModel,
            Controller: MapController,
            Renderer: MapRenderer,
        },
    });
    
    • adding the view to the registry:
      像往常一样,需要更新视图类型和实际类之间的映射:
    var viewRegistry = require('web.view_registry');
    
    viewRegistry.add('map', MapView);
    
    • implementing the four main classes:
      View类需要解析arch字段并设置其他三个类。 Renderer负责在用户界面中表示数据,Model应该与服务器通信,加载数据并处理它。 Controller在那里协调,与网络客户交谈,......

    • creating some views in the database:

    <record id="customer_map_view" model="ir.ui.view">
        <field name="name">customer.map.view</field>
        <field name="model">res.partner</field>
        <field name="arch" type="xml">
            <map latitude="partner_latitude" longitude="partner_longitude">
                <field name="name"/>
            </map>
        </field>
    </record>
    

    Customizing an existing view

    假设我们需要创建通用视图的自定义版本。 例如,一个看板视图,顶部有一些额外的带状(ribbon-like )小部件(显示一些特定的自定义信息)。 在这种情况下,这可以通过3个步骤完成: 1.扩展看板视图(也可能意味着扩展控制器/渲染器和/或模型),
    2.然后在视图注册表中注册视图,
    最后,3.使用看板arch中的视图 (具体示例是帮助台仪表板)。

    • extending a view:
      这是它的样子:
    var HelpdeskDashboardRenderer = KanbanRenderer.extend({
        ...
    });
    
    var HelpdeskDashboardModel = KanbanModel.extend({
        ...
    });
    
    var HelpdeskDashboardController = KanbanController.extend({
        ...
    });
    
    var HelpdeskDashboardView = KanbanView.extend({
        config: _.extend({}, KanbanView.prototype.config, {
            Model: HelpdeskDashboardModel,
            Renderer: HelpdeskDashboardRenderer,
            Controller: HelpdeskDashboardController,
        }),
    });
    
    • adding it to the view registry:
      像往常一样,我们需要通知Web客户端视图名称和实际类之间的映射。
    var viewRegistry = require('web.view_registry');
    viewRegistry.add('helpdesk_dashboard', HelpdeskDashboardView);
    
    • using it in an actual view:
      我们现在需要通知Web客户端特定的ir.ui.view需要使用我们的新类。 请注意,这是Web客户端特定的问题。 从服务器的角度来看,我们仍然有看板视图。 执行此操作的正确方法是在arch的根节点上使用特殊属性js_class(将在某天重命名为widget,因为这实际上不是一个好名称):
    <record id="helpdesk_team_view_kanban" model="ir.ui.view" >
        ...
        <field name="arch" type="xml">
            <kanban js_class="helpdesk_dashboard">
                ...
            </kanban>
        </field>
    </record>
    

    注意:您可以更改视图解释arch结构的方式。 但是,从服务器的角度来看,这仍然是相同基本类型的视图,受到相同的规则(例如,rng验证)。 因此,您的视图仍需要具有有效的arch字段。

  • 相关阅读:
    python 执行sql得到字典格式数据
    python爬虫 url链接编码成gbk2312格式
    windows环境下elasticsearch安装教程(单节点)
    python SQLServer 存储图片
    爬虫的本质是和分布式爬虫的关系
    requests form data 请求 爬虫
    mysql 删除 binlog 日志文件
    查看mysql数据表的大小
    xshell 连接报错 Disconnected from remote host
    centos 7.3 安装 mysqldb 报错 EnvironmentError: mysql_config not found ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  • 原文地址:https://www.cnblogs.com/myt2000/p/10997926.html
Copyright © 2011-2022 走看看