サービス¶
サービスは、機能を提供するコードの長い部分です。 これらはコンポーネント(useService``と共に)または他のサービスによってインポートすることができます。また、依存関係のセットを宣言することもできます。 その意味で、サービスは基本的に DI :dfn:`依存注入` システムです。 例えば、``notification
サービスは通知を表示する方法を提供します。 または、 rpc
サービスは、Odoo サーバーへのリクエストを実行するための適切な方法です。
以下の例では、5秒ごとに通知を表示するシンプルなサービスを登録します。
import { registry } from "@web/core/registry";
const myService = {
dependencies: ["notification"],
start(env, { notification }) {
let counter = 1;
setInterval(() => {
notification.add(`Tick Tock ${counter++}`);
}, 5000);
}
};
registry.category("services").add("myService", myService);
起動時に、Webクライアントは`services`レジストリにあるすべてのサービスを開始します。 レジストリで使用される名前はサービスの名前です。
注釈
コンポーネントではないほとんどのコードは、サービス内で*パッケージ化*されるべきです。特に、副作用がある場合は特に。 これはテスト目的に非常に便利です。テストはアクティブなサービスを選択できます。 つまりテストされるコードに邪魔される望ましくない副作用が
サービスの定義¶
サービスは以下のインターフェイスを実装する必要があります。
- dependencies¶
任意の文字列リスト。このサービスが必要とするすべての依存関係(他のサービス)のリストです。
- start(env, deps)¶
- 引数
env (
Environment()
) -- アプリケーションの環境deps (
Object()
) -- 要求された依存関係のすべて
- 戻り値
value of service or Promise<value of service>
これはサービスのメイン定義です。値またはpromiseのいずれかを返すことができます。 その場合、サービス・ローダーは単にサービスの値である値に解決するpromiseを待つだけです。
一部のサービスは値をエクスポートしません。他のコードから直接呼び出す必要がなくても作業を行うことができます。 その場合、値は
env.services
のnull
に設定されます。
- async¶
任意の値。与えられた場合は、
true
または文字列のリストにする必要があります。一部のサービスでは、非同期APIを提供する必要があります。 例えば、
rpc
サービスは非同期関数であるか、orm
サービスは Odoo サーバーを呼び出す関数のセットを提供します。この場合、非同期関数呼び出しの終了前にサービスを使用するコンポーネントが破棄される可能性があります。 ほとんどの場合、非同期関数呼び出しは無視する必要があります。 それ以外の場合は、元のコンポーネントがアクティブになっていないため、非常に危険な可能性があります。
async
フラグは、コンポーネントが破棄された場合、コンポーネントからのすべての非同期呼び出しを保留状態のままにするようにサービス作成者に通知します。
サービスの使用¶
他のサービスに依存し、dependencies
を適切に宣言したサービスは、start
メソッドの第二引数で対応するサービスへの参照を受け取るだけです。
useService
フックは、コンポーネントでサービスを使用するための適切な方法です。 これは単にサービス値への参照を返し、後でコンポーネントによって使用することができます。例えば:
import { rpc } from "@web/core/network/rpc";
class MyComponent extends Component {
setup() {
onWillStart(async () => {
const result = await rpc(...);
})
}
}
参照リスト¶
技術名 |
簡単な説明 |
---|---|
Cookie の読み取りまたは変更 |
|
グラフィカルエフェクトを表示 |
|
低レベルのhttpコールを実行する |
|
通知を表示 |
|
ブラウザのURLを管理する |
|
サーバーへのリクエストの送信 |
|
アンカー要素のクリックを処理する |
|
ウィンドウのタイトルを読んだり変更したりします |
|
は、現在のユーザーに関連する情報を提供します。 |
概要¶
技術名:
cookie
依存関係: なし
クッキーを操作する方法を提供します。例えば:
cookieService.setCookie("hello", "odoo");
API¶
- current¶
それぞれのクッキーとその値を表すオブジェクト (または空文字列)
- setCookie(name[, value, ttl])¶
- 引数
name (
string()
) -- 設定すべきクッキーの名前value (
any()
) -- 任意です。与えられた場合、クッキーはその値に設定されます。ttl (
number()
) -- 任意です。クッキーが削除されるまでの秒数(デフォルト=1年)
`name`を`ttl`の最大年齢で値`value`に設定します。
- deleteCookie(name)¶
- 引数
name (
string()
) -- クッキーの名前
Cookie の
name
を削除します。
エフェクトサービス¶
概要¶
技術名:
effect
依存関係: なし
エフェクトとは、ページの上部に一時的に表示されるグラフィカル要素であり、通常、何か面白いことが起こったというフィードバックをユーザーに提供します。
良い例としては、虹の男性です:

これを表示する方法は次のとおりです。
const effectService = useService("effect");
effectService.add({
type: "rainbow_man", // can be omitted, default type is already "rainbow_man"
message: "Boom! Team record for the past 30 days.",
});
警告
フック`useEffect`はエフェクトサービスとは関係ありません。
API¶
- effectService.add(options)¶
- 引数
options (
object()
) -- を選択します。
効果を表示する
オプションは次の方法で定義されます:
interface EffectOptions {
// The name of the desired effect
type?: string;
[paramName: string]: any;
}
利用可能なエフェクト¶
現在、唯一の効果は虹の男です。
RainbowMan¶
effectService.add({ type: "rainbow_man" });
名前(name) |
型 |
説明 |
---|---|---|
|
|
RainbowMan内部でインスタンス化するコンポーネントクラス(メッセージを置き換えます)。 |
|
|
params.Component が与えられた場合、props はこの引数で渡すことができます。 |
|
|
メッセージはレインボーマンが保持している通知です。 ユーザーに対してエフェクトが無効になっている場合、レインボーマンは表示されず、単純な通知がフォールバックとして表示されます。 もしエフェクトが有効になっていて、params.Component が指定されている場合、 params.message は使用されません。 メッセージは単純な文字列またはhtmlを表す文字列です(DOM内でインタラクションが必要な場合はparams.Component を使用することを好みます)。 |
|
|
メッセージが html を表す場合は true に設定します。このメッセージは DOM に正しく挿入されます。 |
|
|
虹の中に表示される画像のURL。 |
|
|
レインボーマンの遅延が消えます。
`"いいえ"は、ユーザーが虹の外のどこかをクリックするまで、虹の男性を画面に表示します。 |
効果を追加する方法¶
エフェクトは effects
というレジストリに保存されます。名前と関数を指定することで、新しいエフェクトを追加できます。
const effectRegistry = registry.category("effects");
effectRegistry.add("rainbow_man", rainbowManEffectFunction);
関数はこの API に従う必要があります:
- <newEffectFunction>(env, params)¶
- 引数
env (
Env()
) -- サービスによって受け取られた環境params (
object()
) -- サービスの add 関数から受け取ったパラメータ。
- 戻り値
({Component, props} | void)
コンポーネントとそのプロパティは何もありません。
この関数はコンポーネントを作成して返さなければなりません。このコンポーネントはエフェクトコンポーネントコンテナ内にマウントされます。
例¶
例えば、ページを見てセピアを追加する効果を追加したいとしましょう。
import { registry } from "@web/core/registry";
import { Component, xml } from "@odoo/owl";
class SepiaEffect extends Component {
static template = xml`
<div style="
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
pointer-events: none;
background: rgba(124,87,0, 0.4);
"></div>
`;
}
export function sepiaEffectProvider(env, params = {}) {
return {
Component: SepiaEffect,
};
}
const effectRegistry = registry.category("effects");
effectRegistry.add("sepia", sepiaEffectProvider);
そして、あなたが望む場所にそれを呼び出すと、結果が表示されます。 ここでは、たとえばどこにでも表示させるために webclient.js で呼び出されます。
const effectService = useService("effect");
effectService.add({ type: "sepia" });

Http サービス¶
概要¶
技術名:
http
依存関係: なし
クライアントとodoのサーバー間のほとんどのやり取りは`RPCs`(XMLHTTPRequest
)ですが、リクエストに対するより低いレベルの制御が必要な場合があります。
このサービスは、get
と post
http requests を送信する方法を提供します。
API¶
- async get(route[, readMethod = "json"])¶
- 引数
route (
string()
) -- リクエストを送信するURLreadMethod (
string()
) -- レスポンスコンテンツの種類。"text", "json", "formData", "blob", "arrayBuffer" にできます。
- 戻り値
readMethod 引数で定義されているフォーマットのリクエストの結果。
Get リクエストを送信します。
- async post(route[, params = {}, readMethod = "json"])¶
- 引数
route (
string()
) -- リクエストを送信するURLparams (
object()
) -- リクエストのフォームデータ部分に設定するキー値データreadMethod (
string()
) -- レスポンスコンテンツの種類。"text", "json", "formData", "blob", "arrayBuffer" にできます。
- 戻り値
readMethod 引数で定義されているフォーマットのリクエストの結果。
ポストリクエストを送信します。
例¶
const httpService = useService("http");
const data = await httpService.get("https://something.com/posts/1");
// ...
await httpService.post("https://something.com/posts/1", { title: "new title", content: "new content" });
通知サービス¶
概要¶
技術名:
notification
依存関係: なし
notification
サービスは画面に通知を表示することができます。
const notificationService = useService("notification");
notificationService.add("I'm a very simple notification");
API¶
- add(message[, options])¶
- 引数
message (
string()
) -- 表示する通知メッセージoptions (
object()
) -- 通知のオプション
- 戻り値
通知を閉じる機能
通知を表示
オプションは次の方法で定義されます:
名前(name)
型
説明
title
文字列
通知にタイトルを追加
タイプ
warning
|dang
|success
|info
種類に応じて背景色を変更します
sticky
boolean
解除されるまで通知を維持するかどうか
className
文字列
通知に追加される追加のCSSクラス
onClose
関数
通知が終了したときに実行されるコールバック:
ボタン
ボタン[] (下記参照)
通知に表示するボタンのリスト
autocloseDelay
数値
通知が自動的に閉じられるまでの時間 (ミリ秒)
ボタンは以下により定義されます:
名前(name)
型
説明
名前
文字列
ボタンのテキスト
onClick
関数
ボタンをクリックしたときに実行するコールバックコード
primary
boolean
ボタンをプライマリボタンとしてスタイル付けするかどうか
例¶
販売取引が手数料のページのいくつかの種類を移動するボタンで行われたときの通知。
// in setup
this.notificationService = useService("notification");
this.actionService = useService("action");
// later
this.notificationService.add("You closed a deal!", {
title: "Congrats",
type: "success",
buttons: [
{
name: "See your Commission",
onClick: () => {
this.actionService.doAction("commission_action");
},
},
],
});

1秒後に閉じる通知:
const notificationService = useService("notification");
const close = notificationService.add("I will be quickly closed");
setTimeout(close, 1000);
ルーターサービス¶
概要¶
技術名:
router
依存関係: なし
`router`サービスは3つの機能を提供します。
現在のルートに関する情報は
アプリケーションがURLを更新する方法は
すべてのハッシュ変更を聞いてアプリケーションの残りの部分に通知します
API¶
- current
現在のルートは
current
キーでアクセスできます。以下の情報を持つオブジェクトです:pathname (string)
: 現在の場所のパス (ほとんどの場合/web
)search (object)
: 各検索キーワード (クエリ文字列) をURLから値にマッピングする辞書。 値が明示的に指定されていない場合、空の文字列が値ですhash (object)
: 上記と同じですが、ハッシュに記述されている値です。
例:
// url = /web?debug=assets#action=123&owl&menu_id=174
const { pathname, search, hash } = env.services.router.current;
console.log(pathname); // /web
console.log(search); // { debug="assets" }
console.log(hash); // { action:123, owl: "", menu_id: 174 }
URL の更新は pushState
メソッドで行われます。
- pushState(hash: object[, replace?: boolean])¶
- 引数
hash (
Object()
) -- オブジェクトはあるキーからある値へのマッピングを含んでいますreplace (
boolean()
) -- true の場合、url は置き換えられます。そうでなければ、hash
のキーと値のペアのみが更新されます。
`hash`オブジェクトの各キーと値のペアでURLを更新します。 値が空文字列に設定されている場合、キーは対応する値なしでURLに追加されます。
true の場合、
replace
引数は、url ハッシュが完全に置き換えられるべきであることをルータに伝えます(そのため、hash
オブジェクトには存在しない値は削除されます)。このメソッドの呼び出しはページをリロードしません。 また、
hashchange
イベントや main bus のROUTE_CHANGE
もトリガーしません。 これは、このメソッドが url のみを更新することを意図しているからです。 このメソッドを呼び出すコードは、画面が同様に更新されていることを確認する責任があります。
例:
// url = /web#action_id=123
routerService.pushState({ menu_id: 321 });
// url is now /web#action_id=123&menu_id=321
routerService.pushState({ yipyip: "" }, replace: true);
// url is now /web#yipyip
最後に、redirect
メソッドは指定された url にブラウザーをリダイレクトします。
- redirect(url[, wait])¶
- 引数
url (
string()
) -- a valid urlwait (
boolean()
) -- true の場合、サーバーの準備が完了するのを待ってからリダイレクトします
ブラウザーを
url
にリダイレクトします。このメソッドはページを再読み込みします。wait
引数はめったに使用されません。サーバーが短期間利用できない場合があります。 通常アドオンのアップデートやインストール操作の直後です
注釈
ルーターサービスは、現在のルートが変更されたときに、 :ref:の メインバス <frontend/framework/bus>
上で ROUTE_CHANGE
イベントを発行します。
RPCサービス¶
概要¶
技術名:
rpc
依存関係: なし
rpc`サービスは、サーバーにリクエストを送信する単一の非同期関数を提供します。 コントローラを呼び出すのはとても簡単です。route (ルート)は最初の引数で、必要に応じて第2引数として ``params`
オブジェクトを与えることができます。
import { rpc } from "@web/core/network/rpc";
// somewhere else, in an async function:
const result = await rpc("/my/route", { some: "value" });
注釈
rpc
サービスは低レベルのサービスとみなされることに注意してください。Odoo コントローラとの相互作用にのみ使用する必要があります。 (最も重要なユースケースである)モデルを扱うには、代わりに orm
サービスを使用してください。
API¶
- rpc(route, params, settings)¶
- 引数
route (
string()
) -- リクエスト対象のルートparams (
Object()
) -- (オプション) サーバーに送信されるパラメータsettings (
Object()
) -- (オプション) リクエストの設定 (下記参照)
settings
オブジェクトには以下が含まれます:xhr
はXMLHTTPRequest
オブジェクトでなければなりません。その場合、rpc
メソッドは新しいオブジェクトを作成する代わりに使用します。 これは、XMLHTTPRequest
API の高度な機能にアクセスするときに便利です。silent (boolean)
もしtrue
に設定されている場合、Webクライアントは保留中のrpcがあるというフィードバックを提供しません。
rpc
サービスは XMLHTTPRequest
オブジェクトを使用してサーバーと通信し、application/json
コンテンツ型で動作するように構成されています。 そのため、リクエストの内容は明らかにJSONシリアライズ可能である必要があります。このサービスで行われる各リクエストは``POST`` httpメソッドを使用します。
サーバーエラーは実際にはHTTPコード200で応答を返しますが、rpc
サービスはエラーとして扱います。
エラー処理¶
rpc は主に 2 つの理由で失敗する可能性があります:
どちらかのodoサーバがエラーを返します(これを``server`` エラーと呼びます)。 その場合、http リクエストは
error
キーを含むレスポンスオブジェクトを含む http コード 200 BUT で返されます。あるいは他の種類のネットワークエラーがあります
rpc が失敗した場合:
rpcを表すプロミスが拒否されたので 呼び出しコードが壊れてしまいます
メインアプリケーション・バス上で
RPC_ERROR
イベントがトリガーされます。イベント・ペイロードにはエラーの原因の説明が含まれています:サーバーエラーの場合(サーバーコードは例外を投げました)。 その場合、ペイロードは次のキーを持つオブジェクトになります。
type = 'server'
message(string)
code(number)
name(string)
(オプション、エラーサービスでエラーを処理する際に適切なダイアログを検索するために使用)subType(string)
(オプション、ダイアログタイトルを決定するためによく使用されます)data(object)
(debug
の中に様々なキーを含むことができる任意のオブジェクト: コールスタックを使用したメインデバッグ情報)
If it is a network error, then the error description is simply an object
{type: 'network'}
. When a network error occurs, a notification is displayed and the server is regularly contacted until it responds. The notification is closed as soon as the server responds.
スクローラーサービス¶
概要¶
技術名:
scroller
依存関係: なし
ユーザーがウェブクライアント内のアンカーをクリックするたびに、このサービスは自動的にターゲット(適切な場合)にスクロールします。
このサービスは、click
をドキュメント上に取得するためのイベントリスナーを追加します。 サービスは href 属性に含まれるセレクターがアンカーと Odoo アクションを区別するために有効であるかどうかをチェックします。 . <a href="#target_element"></a>
). そうでない場合は何も行いません。
メインアプリケーション・バス上で SCROLLER:ANCHOR_LINK_CLICKED
イベントがトリガーされます。 このイベントには、element
matching と id
を参照として含むカスタムイベントが含まれています。 他の部分がアンカー自身からの相対的な振る舞いを処理できるようにすることができます。 元のイベントも予防する必要があるかもしれませんので、与えられます。 イベントが防止されない場合、ユーザーインターフェイスはターゲット要素までスクロールします。
API¶
上で説明した anchor-link-clicked
カスタムイベントには、次の値が含まれています。
名前(name) |
型 |
説明 |
---|---|---|
|
|
href が対象とするアンカー要素 |
|
|
href に含まれる id |
|
|
元のクリックイベント |
注釈
scrollerサービスは、 メインバス 上で SCROLLER:ANCHOR_LINK_CLICK_CLICKED
イベントを発行します。 スクロールサービスのデフォルトの動作を避けるために リスナーから自分の動作を正しく実装できるように、リスナーに与えられたイベントに preventDefault()
を使用する必要があります。
タイトルサービス¶
概要¶
技術名:
title
依存関係: なし
title
サービスは、ドキュメントのタイトルを読んだり変更したりできるシンプルなAPIを提供します。 例えば、現在のドキュメントのタイトルが「Odoo」の場合、次のコマンドを使用して「Odoo 15 - Apple」に変更できます。
// in some component setup method
const titleService = useService("title");
titleService.setParts({ odoo: "Odoo 15", fruit: "Apple" });
API¶
title
サービスは以下のインターフェイスを操作します。
interface Parts {
[key: string]: string | null;
}
各キーは、タイトルの一部の識別を表します。 そして、それぞれの値は表示される文字列、もしくは削除された場合は nullです。
API は次の通りです:
- current
これは現在のタイトルを表す文字列です。
value_1 - ... - value_n
各`value_i` は (null ではない) 値です (getParts
関数によって返されます)
- getParts()¶
- 戻り値
タイトルサービスによって維持されている現在の
Parts
オブジェクトのパーツ
- setParts(parts)¶
- 引数
parts (
Parts()
) -- 必要な変更を表すオブジェクト
setParts
メソッドでは、タイトルの複数の部分を追加/置き換え/削除できます。 パーツ(値)を削除するには、関連するキーの値をnull
に設定します。1つは他のパートに影響を与えることなく、1つのパートしか変更できないことに注意してください。例えば、タイトルが次のパートで構成されている場合:
{ odoo: "Odoo", action: "Import" }
current
の値はOdoo - Import
で、setParts({ action: null, });
タイトルを
Odoo
に変更します。
ユーザーサービス¶
概要¶
技術名:
user
依存関係:
rpc
`user`サービスは、データの束と接続されたユーザーに関するいくつかのヘルパー関数を提供します。
API¶
名前(name) |
型 |
説明 |
---|---|---|
|
|
|
|
|
データベースに関する情報 |
|
|
ユーザのホームとして使用されるアクションの Id |
|
|
ユーザーが管理者であるかどうか(グループ |
|
|
ユーザーがシステムグループ ( |
|
|
使用言語 |
|
|
ユーザーの名前 |
|
|
ユーザーのパートナーインスタンスの Id |
|
|
利用者のタイムゾーン |
|
|
利用者ID |
|
|
ユーザーの代替ニックネーム: |
- updateContext(update)¶
- 引数
update (
object()
) -- コンテキストを更新するオブジェクト
user context を指定したオブジェクトで更新します。
userService.updateContext({ isFriend: true })