说明:这是对Odoo官方Owl公开的资料的翻译。以后再添加我在Odoo的Owl源码中领悟到的技术说明
这篇文章的确很烧脑,但是也只能从这里先学习,以后可以回过头来再看看这篇文章,会觉得很清晰。
建议先学习typescript和Qweb的知识
对于本教程,我们将构建一个非常简单的待办事项列表应用程序。 该应用程序应满足以下要求:
- 让用户创建和删除任务
- 任务可以标记为已完成
- 可以过滤任务以显示活动/已完成的任务
这个项目将是发现和学习一些重要的Owl概念的机会,例如组件,存储以及如何组织应用程序。
1.建立项目
对于本教程,我们将做一个非常简单的项目,其中包含静态文件,并且没有其他工具。 第一步是创建以下文件结构:
![cfd716f1e2aec78db3e45cbeddb1efc3.png](https://img-blog.csdnimg.cn/img_convert/cfd716f1e2aec78db3e45cbeddb1efc3.png)
该应用程序的入口点是文件index.html,该文件应具有以下内容:
OWL Todo App
然后,可以暂时将app.css留空。 以后对我们的应用程序进行样式设置将很有用。 app.js是我们编写所有代码的地方。 现在,我们只需要输入以下代码:
(function () { console.log("hello owl", owl.__info__.version);})();
请注意,我们将所有内容放入立即执行的函数中,以避免将任何内容泄漏到全局范围。
最后,owl.js应该是从Owl存储库下载的最新版本(如果愿意,可以使用owl.min.js)。
现在,该项目应该已经准备好了。 将index.html文件加载到浏览器中时,应显示一个空白页面,标题为Owl Todo App,并且应在控制台中记录一条消息,例如hello owl 1.0.0。
2.添加第一个组件
Owl应用程序由组件组成(https://github.com/odoo/owl/blob/master/doc/reference/component.md),具有单个根组件。 让我们首先定义一个App组件。 通过以下代码替换app.js中函数的内容:
const { Component } = owl;const { xml } = owl.tags;const { whenReady } = owl.utils;// Owl Componentsclass App extends Component { static template = xml`
todo app
`;}// Setup codefunction setup() { const app = new App(); app.mount(document.body);}whenReady(setup);
现在,在浏览器中重新加载页面应该显示一条消息。
代码非常简单,但是让我们更详细地解释最后一行。浏览器尝试尽快执行app.js中的javascript代码,并且当我们尝试安装App组件时,可能发生DOM尚未准备就绪的情况。为了避免这种情况,我们使用whenReady帮助程序将setup函数的执行延迟到DOM准备就绪为止。
注意1:在更大的项目中,我们将代码分成多个文件,组件位于子文件夹中,而主文件则将初始化应用程序。但是,这是一个很小的项目,我们希望使其尽可能简单。
注意2:本教程使用静态类字段语法。并非所有浏览器都支持此功能。大多数实际项目都会转换其代码,因此这不是问题,但是对于本教程而言,如果您需要在每个浏览器上都能使用的代码,则需要将每个static关键字转换为对该类的分配:
class App extends Component {}App.template = xml`
todo app
`;
注意3:使用xml helper(https://github.com/odoo/owl/blob/master/doc/reference/tags.md#xml-tag)编写内联模板是不错的选择,但是没有突出显示语法,这使得格式错误的xml非常容易。 一些编辑器在这种情况下支持语法突出显示。 例如,VS Code具有附加Comment tagged template,如果已安装,它将正确显示标签模板:
static template = xml /* xml */`
todo app
`;
注4:大型应用程序可能希望能够翻译模板。 使用内联模板会使它稍微困难一些,因为我们需要其他工具来从代码中提取xml,并将其替换为转换后的值。
3.显示任务列表
现在已经完成了基础工作,是时候开始考虑任务了。 为了完成我们需要的工作,我们将使用以下键将任务作为对象数组来跟踪:
- id:一个数字。 拥有一种唯一标识任务的方法非常有用。 由于标题是用户创建/编辑的内容,因此无法保证其唯一性。 因此,我们将为每个任务生成一个唯一的ID号。
- title:一个字符串,用来说明任务的含义。
- isCompleted:一个布尔值,用于跟踪任务的状态
现在,我们决定了状态的内部格式,让我们向App组件添加一些演示数据和模板:
![d2b4ff65504bfc9041a4936039cd323e.png](https://img-blog.csdnimg.cn/img_convert/d2b4ff65504bfc9041a4936039cd323e.png)
该模板包含一个t-foreach循环以迭代任务。 因为组件是渲染上下文,所以它可以从组件中找到tasks列表。 请注意,我们将每个任务的id用作t-key,这很常见。 有两个CSS类:task-list和task,我们将在下一节中使用它们。
最后,请注意t-att-checked</