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字段。

  • 相关阅读:
    常见mysql中出现的问题
    php 根据身份证号相关操作
    Linux的上传文件和下载文件
    php实现socket
    PHP开启缓存加速
    spark使用Hive表操作
    部署ganglia3.7
    Redis Cluster架构优化
    spark读取hdfs数据本地性异常
    spark join broadcast优化
  • 原文地址:https://www.cnblogs.com/myt2000/p/10997926.html
Copyright © 2011-2022 走看看