创建一个独立的 Owl 应用程序

出于各种原因,您可能希望拥有一个不属于网页客户端的独立 Owl 应用程序。Odoo 中的一个例子是自助点餐应用,它允许顾客通过手机点餐。在本章中,我们将探讨实现类似功能所需的条件。

概述

要拥有一个独立的 Owl 应用程序,需要满足以下几点:

  • 应用程序的根组件

  • 一个包含设置代码的资源包

  • 一个调用资源包的 QWeb 视图

  • 一个渲染视图的控制器

1. Root component

为了简单起见,让我们从一个非常直接的组件开始,它只渲染 “Hello, World!”。这将让我们一眼就能知道我们的设置是否正常工作。

首先,在 /your_module/static/src/standalone_app/root.xml 中创建模板。

<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
    <t t-name="your_module.Root">
        Hello, World!
    </t>
</templates>

然后在 /your_module/static/src/standalone_app/root.js 中为该组件创建 JavaScript 文件。

import { Component } from "@odoo/owl";

export class Root extends Component {
    static template = "your_module.Root";
    static props = {};
}

通常建议将挂载组件的应用程序设置代码放在单独的文件中。创建将在 /your_module/static/src/standalone_app/app.js 中挂载应用程序的 JavaScript 文件。

import { whenReady } from "@odoo/owl";
import { mountComponent } from "@web/env";
import { Root } from "./root";

whenReady(() => mountComponent(Root, document.body));

mountComponent 实用函数将负责创建 Owl 应用程序并正确配置它:它将创建一个环境,启动 services,确保应用程序被翻译,并让应用程序访问资产包中的模板,以及其他事项。

另请参阅

Owl 组件参考

2. Creating an assets bundle containing our code

在模块的清单中,创建一个新的 资源包。它应该包含 web._assets_core 资源包,该资源包包含了 Odoo JavaScript 框架及其所需的核心库(例如 Owl 和 luxon),之后你可以使用一个 glob 将所有应用程序的文件添加到该资源包中。

{
    # ...
    'assets': {
        'your_module.assets_standalone_app': [
            ('include', 'web._assets_helpers'),
            'web/static/src/scss/pre_variables.scss',
            'web/static/lib/bootstrap/scss/_variables.scss',
            ('include', 'web._assets_bootstrap'),
            ('include', 'web._assets_core'),
            'your_module/static/src/standalone_app/**/*',
        ],
    }
}

其他几行是使 Bootstrap 正常工作所需的 bundles 和 scss 文件。它们是必需的,因为 Web 框架的组件使用 bootstrap 类进行样式和布局。

小心

确保您的独立应用程序的文件仅添加到此捆绑包中,如果您已经定义了 web.assets_backendweb.assets_frontend 并且它们包含 globs,请确保这些 globs 不匹配您的独立应用程序的文件,否则您的应用程序的启动代码将与这些捆绑包中的现有启动代码发生冲突。

另请参阅

模块清单参考

3. XML view that calls the assets bundle

既然我们已经创建了我们的资源包,我们需要创建一个使用该资源包的 QWeb 视图

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <template id="your_module.standalone_app">&lt;!DOCTYPE html&gt;
        <html>
            <head>
                <script type="text/javascript">
                    var odoo = {
                        csrf_token: "<t t-nocache="The csrf token must always be up to date." t-esc="request.csrf_token(None)"/>",
                        debug: "<t t-out="debug"/>",
                        __session_info__: <t t-esc="json.dumps(session_info)"/>,
                    };
                </script>
                <t t-call-assets="your_module.assets_standalone_app" />
            </head>
            <body/>
        </html>
    </template>
</odoo>

此模板仅执行两项操作:初始化 odoo 全局变量,然后调用我们刚刚定义的资源包。初始化 odoo 全局变量是必要的一步。此变量应为一个包含以下内容的对象:

  • CSRF 令牌,在许多情况下与 HTTP 控制器交互时需要。

  • 调试值,在许多地方用于添加额外的日志记录或开发者友好的检查。

  • __session_info__,它包含来自服务器的信息,这些信息始终是必需的,并且我们不希望为此执行额外的请求。更多内容将在下一节中介绍。

4. Controller that renders the view

既然我们已经有了视图,我们需要让用户能够访问它。为此,我们将创建一个 HTTP controller 来渲染该视图并将其返回给用户。

from odoo.http import request, route, Controller

class YourController(Controller):
    @route("/your_module/standalone_app", auth="public")
    def standalone_app(self):
        return request.render(
            'your_module.standalone_app',
            {
                'session_info': request.env['ir.http'].get_frontend_session_info(),
            }
        )

注意我们是如何给模板 session_info 的。我们从 get_frontend_session_info 方法中获取它,它最终将包含 web 框架使用的信息,例如当前用户的 ID(如果他们已登录)、服务器版本、Odoo 版本等。

此时,如果您在浏览器中打开网址 /your_module/standalone_app ,您应该会看到一个空白页面,上面显示文本 “Hello, World!”。此时,您可以开始实际编写应用程序的代码。