第三章:字段和視圖?
在上一章中,我們學習了一系列技能,包括如何創建和使用服務,使用布局組件,使儀表板可翻譯,并延遲加載像Chart.js這樣的JavaScript庫?,F在,讓我們繼續學習如何創建新的字段和視圖。
這是我們在 第二章:Odoo Web框架 結束時發現 JavaScript web 框架的進展。?
字段和視圖是Odoo用戶界面中最重要的概念之一。它們是許多重要用戶交互的關鍵,因此應該完美地工作。
在 JavaScript 框架的上下文中,字段是專門用于可視化/編輯給定記錄的特定字段的組件。
例如,一個(Python)模型可以定義一個字符字段,該字段將由字段組件“CharField”表示。
一個字段組件基本上只是在 fields
registry 中注冊的組件。字段組件可以定義一些額外的靜態鍵(元數據),例如 displayName
或 supportedTypes
,以及最重要的一個: extractProps
,它準備了由 CharField
接收的基本 props。
Example
讓我們討論一個 CharField
的簡化實現。
首先,這是模板:
<t t-name="web.CharField" owl="1">
<t t-if="props.readonly">
<span t-esc="formattedValue" />
</t>
<t t-else="">
<input
class="o_input"
t-att-type="props.isPassword ? 'password' : 'text'"
t-att-placeholder="props.placeholder"
t-on-change="updateValue"
/>
</t>
</t>
它具有只讀模式和編輯模式,后者是帶有一些屬性的輸入?,F在,這是JavaScript代碼:
export class CharField extends Component {
get formattedValue() {
return formatChar(this.props.value, { isPassword: this.props.isPassword });
}
updateValue(ev) {
let value = ev.target.value;
if (this.props.shouldTrim) {
value = value.trim();
}
this.props.update(value);
}
}
CharField.template = "web.CharField";
CharField.displayName = _lt("Text");
CharField.supportedTypes = ["char"];
CharField.extractProps = ({ attrs, field }) => {
return {
shouldTrim: field.trim && !archParseBoolean(attrs.password),
maxLength: field.size,
isPassword: archParseBoolean(attrs.password),
placeholder: attrs.placeholder,
};
};
registry.category("fields").add("char", CharField);
有幾個重要的事情需要注意:
CharField
在props
中接收到它的(原始)值。在顯示之前,需要對其進行格式化。它在其props中接收一個
update
函數,該函數由字段用于通知狀態所有者該字段的值已更改。請注意,字段不會(也不應該)維護其值的本地狀態。每當更改已應用時,它將通過props的方式返回(可能在onchange之后)。它定義了一個
extractProps
函數。這是一個將通用標準屬性轉換為視圖特定專用屬性的步驟,這些屬性對組件非常有用。這使得組件具有更好的 API,并且可能使其可重用。
字段必須在“字段”注冊表中注冊。一旦完成,它們可以在某些視圖(即: form
, list
, kanban
)中使用 widget
屬性。
Example
<field name="preview_moves" widget="account_resequence_widget"/>
目標

本章節中每個練習的解決方案都托管在 官方Odoo教程存儲庫 中。
1. image_preview
字段?
網站上的每個新訂單都將被創建為 awesome_tshirt.order
。此模型具有 image_url
字段(類型為 char
),目前僅以字符串形式可見。我們希望在表單視圖中能夠看到它。
為了完成此任務,我們需要創建一個新的字段組件 image_preview
。該組件的規格如下:在只讀模式下,如果字段已設置,則僅為帶有正確 src
的圖像標簽;在編輯模式下,它也像經典的 char
字段一樣運行(您可以通過將其傳遞給 props 在模板中使用 CharField
)。應該顯示一個 input
,其中包含字段的文本值,以便進行編輯。
Exercise
創建一個新的
ImagePreview
組件并在模板中使用CharField
組件。您可以使用 t-props 將ImagePreview
接收到的 props 傳遞給CharField
。在正確的 注冊表 中注冊您的字段。
通過設置“widget”屬性,更新表單視圖的結構以使用您的新字段。
注解
雖然可以通過繼承 CharField
來解決這個練習,但是這個練習的目標是從頭開始創建一個字段。

另請參閱
2. 改進 image_preview
字段?
Exercise
我們想要改進上一個任務的字段,以幫助員工識別需要執行某些操作的訂單。特別是,如果訂單上沒有指定圖像URL,我們想要以紅色顯示警告”缺少T恤設計”。

3. 自定義字段組件?
讓我們看看如何使用繼承來擴展現有組件。
任務模型上有一個只讀的布爾字段 is_late
。在列表/看板/視圖上看到這個信息會很有用。然后,假設我們想在它被設置為true時在旁邊添加一個紅色的單詞“Late!”。
Exercise
創建一個繼承自
BooleanField
的新LateOrderBoolean
字段。LateOrderBoolean
的模板也可以從BooleanField
模板中 繼承 。在列表/看板/表單視圖中使用它。
按照要求修改它,在旁邊添加一個紅色的“遲到”字樣。

另請參閱
4. 針對某些客戶的消息?
Odoo表單視圖支持 widget
API,它類似于字段,但更通用。它可用于在表單視圖中插入任意組件。讓我們看看如何使用它。
Exercise
為了實現高效的工作流程,我們希望在表單視圖中顯示一個帶有一些信息的消息/警告框,具體的消息取決于某些條件:
如果
image_url
字段未設置,則應顯示“無圖像”。如果訂單金額超過100歐元,則應顯示“添加促銷材料”。
確保您的小部件實時更新。

5. 使用 markup
?
讓我們看看如何在模板中顯示原始HTML。以前有一個 t-raw
指令,它會將任何東西都輸出為HTML。這是不安全的,已經被一個 t-out <https://github.com/odoo/owl/blob/master/doc/reference/templates.md#outputting-data>`_指令所取代,它的作用類似于 `t-esc
,除非數據已經明確地使用 markup
函數標記。
Exercise
修改前一個練習,將“image”和“material”這兩個詞加粗。
警告應該被標記,模板應該被修改為使用
t-out
。
注解
這是一個 t-out
的安全使用示例,因為字符串是靜態的。

7. 自動重新加載看板視圖?
Bafien很不高興:他想在外部顯示器上看到T恤訂單的看板視圖,但視圖需要保持最新狀態。他厭倦了每30秒點擊 刷新 圖標,所以他委托你找到一種自動執行的方法。
就像之前的練習一樣,這種定制需要創建一個新的JavaScript視圖。
Exercise
擴展看板視圖/控制器,使其每分鐘重新加載數據。
在視圖注冊表中注冊它,名稱為
awesome_tshirt.autoreloadkanban
。在看板視圖的arch中使用它(使用
js_class
屬性)。
重要
如果您使用 setInterval
或類似的東西,請確保在組件卸載時正確取消它。否則,您將引入內存泄漏。