Szolgáltatások¶
A szolgáltatások hosszú élettartamú kódrészek, amelyek egy funkciót biztosítanak. Importálhatók komponensek által (useService-szel) vagy más szolgáltatások által. Továbbá, deklarálhatnak egy függőségi halmazt. Ebben az értelemben a szolgáltatások alapvetően egy DI függőség injektálási rendszer. Például a notification szolgáltatás lehetőséget biztosít egy értesítés megjelenítésére, vagy az rpc szolgáltatás a megfelelő módja annak, hogy kérést hajtsunk végre az Odoo szerver felé.
A következő példa regisztrál egy egyszerű szolgáltatást, amely 5 másodpercenként megjelenít egy értesítést:
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);
Induláskor a web kliens elindítja az összes szolgáltatást, amely jelen van a services regisztrációs táblában. Vegyük figyelembe, hogy a regisztrációs táblában használt név a szolgáltatás neve.
Megjegyzés
A legtöbb kód, amely nem komponens, csomagolva kell legyen egy szolgáltatásban, különösen, ha valamilyen mellékhatást fejt ki. Ez nagyon hasznos tesztelési célokra: a tesztek kiválaszthatják, mely szolgáltatások aktívak, így kisebb az esélye annak, hogy nem kívánt mellékhatások zavarják a tesztelt kódot.
Szolgáltatás definiálása¶
Egy szolgáltatásnak a következő interfészt kell megvalósítania:
- dependencies¶
Opcionális karakterlánc lista. Ez a lista tartalmazza az összes függőséget (más szolgáltatásokat), amelyekre ennek a szolgáltatásnak szüksége van
- start(env, deps)¶
- Argumentum
env (
Environment()) – az alkalmazás környezetedeps (
Object()) – az összes kért függőség
- Visszatérési érték
a szolgáltatás értéke vagy Promise<szolgáltatás értéke>
Ez a szolgáltatás fő definíciója. Visszaadhat egy értéket vagy egy ígéretet. Ebben az esetben a szolgáltatás betöltője egyszerűen megvárja, amíg az ígéret egy értékre oldódik fel, amely aztán a szolgáltatás értéke lesz.
Néhány szolgáltatás nem exportál semmilyen értéket. Lehet, hogy csak elvégzik a munkájukat anélkül, hogy más kód közvetlenül hívná őket. Ebben az esetben az értékük
nulllesz azenv.services-ben.
- async¶
Opcionális érték. Ha meg van adva, akkor
truevagy egy karakterláncok listája kell legyen.Néhány szolgáltatásnak aszinkron API-t kell biztosítania. Például az
rpcszolgáltatás egy aszinkron függvény, vagy azormszolgáltatás egy sor függvényt biztosít az Odoo szerver hívásához.Ebben az esetben lehetséges, hogy a szolgáltatást használó komponensek megsemmisülnek az aszinkron függvényhívás vége előtt. A legtöbb esetben az aszinkron függvényhívást figyelmen kívül kell hagyni. Másképp cselekedni potenciálisan nagyon kockázatos, mert az alapul szolgáló komponens már nem aktív. Az
asyncjelző egy módja annak, hogy ezt megtegyük: jelzi a szolgáltatás létrehozójának, hogy minden aszinkron hívást, amely a komponensekből érkezik, függőben kell hagyni, ha a komponens megsemmisül.
Szolgáltatás használata¶
Egy szolgáltatás, amely más szolgáltatásoktól függ és megfelelően deklarálta a dependencies-t, egyszerűen megkapja a megfelelő szolgáltatások hivatkozását a start metódus második argumentumában.
A useService hook a megfelelő módja annak, hogy egy szolgáltatást használjunk egy komponensben. Egyszerűen visszaad egy hivatkozást a szolgáltatás értékére, amelyet a komponens később használhat. Például:
import { rpc } from "@web/core/network/rpc";
class MyComponent extends Component {
setup() {
onWillStart(async () => {
const result = await rpc(...);
})
}
}
Referencia lista¶
Technikai név |
Rövid leírás |
|---|---|
sütik olvasása vagy módosítása |
|
grafikus hatások megjelenítése |
|
alacsony szintű http hívások végrehajtása |
|
értesítések megjelenítése |
|
a böngésző URL kezelése |
|
kérések küldése a szerverre |
|
horgony elemek kattintásainak kezelése |
|
az ablak címének olvasása vagy módosítása |
|
bizonyos információkat nyújt a jelenlegi felhasználóval kapcsolatban |
Áttekintés¶
Technikai név:
cookieFüggőségek: nincsenek
Lehetőséget biztosít a sütik kezelésére. Például:
cookieService.setCookie("hello", "odoo");
API¶
- current¶
Objektum, amely minden sütit és annak értékét képviseli, ha van (vagy üres string)
- setCookie(name[, value, ttl])¶
- Argumentum
name (
string()) – a süti neve, amelyet be kell állítanivalue (
any()) – opcionális. Ha meg van adva, a süti erre az értékre lesz beállítvattl (
number()) – opcionális. az idő másodpercben, mielőtt a süti törlődik (alapértelmezett=1 év)
Beállítja a
namesütit avalueértékrettlmaximális élettartammal
- deleteCookie(name)¶
- Argumentum
name (
string()) – a süti neve
Törli a
namesütit.
Hatás szolgáltatás¶
Áttekintés¶
Technikai név:
effectFüggőségek: Nincsenek
A hatások grafikai elemek, amelyek ideiglenesen megjelenhetnek az oldal tetején, általában azért, hogy visszajelzést adjanak a felhasználónak arról, hogy valami érdekes történt.
Jó példa erre a szivárványember:
Így jeleníthető meg:
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.",
});
Figyelem
A useEffect hook nem kapcsolódik a hatás szolgáltatáshoz.
API¶
- effectService.add(options)¶
- Argumentum
options (
object()) – a hatás beállításai. Ezek továbbítva lesznek az alapul szolgáló hatás komponenshez.
Egy hatás megjelenítése.
A beállításokat az alábbiak határozzák meg:
interface EffectOptions {
// The name of the desired effect
type?: string;
[paramName: string]: any;
}
Elérhető hatások¶
Jelenleg az egyetlen hatás a szivárványember.
RainbowMan¶
effectService.add({ type: "rainbow_man" });
Név |
Típus |
Leírás |
|---|---|---|
|
|
A Component osztály példányosítása a RainbowMan belsejében (ez helyettesíti az üzenetet). |
|
|
Ha a params.Component meg van adva, annak props értékei ezzel az argumentummal adhatók át. |
|
|
Az üzenet az értesítés, amit a rainbowman tart. Ha a felhasználó számára le vannak tiltva a hatások, a rainbowman nem jelenik meg, és egy egyszerű értesítés jelenik meg helyette. Ha a hatások engedélyezve vannak és a params.Component meg van adva, a params.message nem kerül felhasználásra. Az üzenet egy egyszerű szöveg vagy egy html-t reprezentáló szöveg (előnyben részesítse a params.Component használatát, ha interakciókat szeretne a DOM-ban). |
|
|
Állítsa igazra, ha az üzenet html-t reprezentál, így helyesen kerül beillesztésre a DOM-ba. |
|
|
A kép URL-je, amelyet a szivárvány belsejében kell megjeleníteni. |
|
|
Késleltetés a szivárványember eltűnéséhez.
|
Hogyan lehet hatást hozzáadni¶
A hatások egy effects nevű nyilvántartásban vannak tárolva. Új hatásokat adhat hozzá egy név és egy függvény megadásával.
const effectRegistry = registry.category("effects");
effectRegistry.add("rainbow_man", rainbowManEffectFunction);
A függvénynek a következő API-t kell követnie:
- <newEffectFunction>(env, params)¶
- Argumentum
env (
Env()) – a szolgáltatás által kapott környezetparams (
object()) – a szolgáltatás add függvényéből kapott paraméterek.
- Visszatérési érték
({Component, props} | void)Egy komponens és annak tulajdonságai vagy semmi.
Ennek a függvénynek létre kell hoznia egy komponenst, és vissza kell adnia azt. Ez a komponens a hatás komponens konténerében van elhelyezve.
Példa¶
Tegyük fel, hogy szeretnénk hozzáadni egy hatást, amely szépia megjelenést ad az oldalnak.
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);
Ezután hívja meg valahol, ahol szeretné, és látni fogja az eredményt. Itt a webclient.js-ben van meghívva, hogy mindenhol látható legyen a példa kedvéért.
const effectService = useService("effect");
effectService.add({ type: "sepia" });
Http szolgáltatás¶
Áttekintés¶
Technikai név:
httpFüggőségek: Nincsenek
Míg az odoo-ban a kliens és a szerver közötti interakciók többsége RPC (XMLHTTPRequest), néha alacsonyabb szintű vezérlésre lehet szükség a kérések felett.
Ez a szolgáltatás lehetőséget biztosít get és post http kérések küldésére.
API¶
- async get(route[, readMethod = "json"])¶
- Argumentum
route (
string()) – az URL, ahová a kérést küldeni kellreadMethod (
string()) – the response content type. Can be „text”, „json”, „formData”, „blob”, „arrayBuffer”.
- Visszatérési érték
a kérés eredménye a readMethod argumentumban meghatározott formátumban.
Get kérés küldése.
- async post(route[, params = {}, readMethod = "json"])¶
- Argumentum
route (
string()) – az URL, ahová a kérést küldeni kellparams (
object()) – kulcs-érték adatok, amelyeket a kérés form adatrészében kell beállítanireadMethod (
string()) – the response content type. Can be „text”, „json”, „formData”, „blob”, „arrayBuffer”.
- Visszatérési érték
a kérés eredménye a readMethod argumentumban meghatározott formátumban.
Post kérés küldése.
Példa¶
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" });
Értesítési szolgáltatás¶
Áttekintés¶
Technikai név:
notificationFüggőségek: Nincsenek
A notification szolgáltatás lehetővé teszi értesítések megjelenítését a képernyőn.
const notificationService = useService("notification");
notificationService.add("I'm a very simple notification");
API¶
- add(message[, options])¶
- Argumentum
message (
string()) – a megjelenítendő értesítési üzenetoptions (
object()) – az értesítés beállításai
- Visszatérési érték
egy függvény az értesítés bezárásához
Értesítést jelenít meg.
A beállításokat az alábbiak határozzák meg:
Név
Típus
Leírás
titlekarakterlánc
Adjon címet az értesítéshez
típusfigyelmeztetés|veszély|siker|információMegváltoztatja a háttérszínt a típusnak megfelelően
ragadóslogikai
Azt jelzi, hogy az értesítés megmaradjon-e, amíg el nem utasítják
osztályNévkarakterlánc
további css osztály, amely hozzáadódik az értesítéshez
bezáráskorfüggvény
visszahívás, amely végrehajtásra kerül, amikor az értesítés bezárul
gombokbutton[] (lásd alább)
a megjelenítendő gombok listája az értesítésben
autocloseDelayszám
duration in milliseconds before the notification is closed automatically
A gombok a következőképpen vannak meghatározva:
Név
Típus
Leírás
namekarakterlánc
A gomb szövege
kattintáskorfüggvény
visszahívás, amely végrehajtódik, amikor a gombot megnyomják
elsődlegeslogikai
meghatározza, hogy a gombot elsődleges gombként kell-e formázni
Példák¶
Értesítés, amikor egy értékesítési üzlet létrejön, egy gombbal, amely egy jutalékoldalra vezet.
// 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");
},
},
],
});
Egy értesítés, amely egy másodperc után bezárul:
const notificationService = useService("notification");
const close = notificationService.add("I will be quickly closed");
setTimeout(close, 1000);
Router Szolgáltatás¶
Áttekintés¶
Technikai név:
routerFüggőségek: nincsenek
A router szolgáltatás három funkciót biztosít:
információ az aktuális útvonalról
egy mód az alkalmazás számára, hogy frissítse az URL-t az állapotától függően
figyeli minden hash változást, és értesíti az alkalmazás többi részét
API¶
- current
Az aktuális útvonal a
currentkulccsal érhető el. Ez egy objektum a következő információkkal:pathname (string): az aktuális hely útvonala (valószínűleg/web)search (object): egy szótár, amely az URL keresési kulcsszavait (a querystringet) értékeikhez rendeli. Üres string az érték, ha nem adtak meg kifejezetten értékethash (object): ugyanaz, mint fent, de a hash-ben leírt értékekre.
Például:
// 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 }
Az URL frissítése a pushState metódussal történik:
- pushState(hash: object[, replace?: boolean])¶
- Argumentum
hash (
Object()) – objektum, amely néhány kulcsot értékekhez rendelreplace (
boolean()) – ha igaz, az URL lecserélődik, ellenkező esetben csak ahashkulcs/érték párok frissülnek.
Frissíti az URL-t a
hashobjektumból származó minden kulcs/érték párral. Ha egy érték üres karakterláncra van állítva, a kulcs hozzáadódik az url-hez bármilyen megfelelő érték nélkül.Ha igaz, a
replaceargumentum azt jelzi a routernek, hogy az url hash-t teljesen le kell cserélni (így ahashobjektumban nem szereplő értékek eltávolításra kerülnek).Ez a metódushívás nem tölti újra az oldalt. Nem vált ki
hashchangeeseményt, semROUTE_CHANGE-t a main bus-ban. Ennek oka, hogy ez a metódus csak az url frissítésére szolgál. A metódust hívó kód felelőssége, hogy biztosítsa a képernyő frissítését is.
Például:
// 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
Végül, a redirect metódus átirányítja a böngészőt egy megadott url-re:
- redirect(url[, wait])¶
- Argumentum
url (
string()) – egy érvényes urlwait (
boolean()) – ha igaz, várja meg, amíg a szerver készen áll, és utána irányítson át
Irányítsa át a böngészőt
url-re. Ez a metódus újratölti az oldalt. Awaitargumentum ritkán használt: hasznos lehet bizonyos esetekben, amikor tudjuk, hogy a szerver rövid ideig nem lesz elérhető, tipikusan közvetlenül egy kiegészítő frissítése vagy telepítése után.
Megjegyzés
A router szolgáltatás ROUTE_CHANGE eseményt bocsát ki a main bus-ban, valahányszor a jelenlegi útvonal megváltozott.
RPC szolgáltatás¶
Áttekintés¶
Technikai név:
rpcFüggőségek: nincsenek
Az rpc szolgáltatás egyetlen aszinkron függvényt biztosít a szerverhez való kérések küldésére. Egy vezérlő meghívása nagyon egyszerű: az útvonalnak kell lennie az első argumentumnak, és opcionálisan egy params objektum adható meg második argumentumként.
import { rpc } from "@web/core/network/rpc";
// somewhere else, in an async function:
const result = await rpc("/my/route", { some: "value" });
Megjegyzés
Vegye figyelembe, hogy az rpc szolgáltatás alacsony szintű szolgáltatásnak minősül. Csak Odoo vezérlőkkel való interakcióra kell használni. A modellekkel való munkához (ami messze a legfontosabb felhasználási eset) inkább az orm szolgáltatást kell használni.
API¶
- rpc(route, params, settings)¶
- Argumentum
route (
string()) – a kérés által célzott útvonalparams (
Object()) – (opcionális) a szervernek küldött paramétereksettings (
Object()) – (opcionális) kérés beállításai (lásd alább)
A
settingsobjektum tartalmazhatja:xhr, amelynek egyXMLHTTPRequestobjektumnak kell lennie. Ebben az esetben azrpcmetódus egyszerűen ezt fogja használni egy új létrehozása helyett. Ez hasznos, amikor azXMLHTTPRequestAPI fejlett funkcióihoz férünk hozzá.silent (boolean)Hatrue-ra van állítva, a web kliens nem ad visszajelzést arról, hogy van egy függőben lévő rpc.
Az rpc szolgáltatás a szerverrel egy XMLHTTPRequest objektum használatával kommunikál, amely az application/json tartalomtípusra van konfigurálva. Így egyértelmű, hogy a kérés tartalmának JSON sorosíthatónak kell lennie. Minden, e szolgáltatás által végzett kérés a POST http metódust használja.
A szerver hibák valójában egy http 200 kóddal térnek vissza. Azonban az rpc szolgáltatás ezeket hibaként fogja kezelni.
Hibakezelés¶
Egy rpc két fő okból hibásodhat meg:
vagy az odoo szerver hibát ad vissza (ezt
szerverhibának nevezzük). Ebben az esetben a http kérés 200-as http kóddal tér vissza, DE egy válaszobjektummal, amely tartalmaz egyerrorkulcsot.vagy valamilyen más hálózati hiba van
Amikor egy rpc meghibásodik, akkor:
az rpc-t képviselő ígéret elutasításra kerül, így a hívó kód összeomlik, hacsak nem kezeli a helyzetet
egy
RPC_ERROResemény kerül kiváltásra a fő alkalmazás buszon. Az esemény terhelése tartalmazza a hiba okának leírását:Ha szerverhiba történt (a szerver kód kivételt dobott). Ebben az esetben az esemény terhelése egy objektum lesz a következő kulcsokkal:
type = 'server'message(string)code(number)name(string)(opcionális, a hibaszolgáltatás használja, hogy megfelelő párbeszédablakot keressen a hiba kezelésekor)subType(string)(opcionális, gyakran a párbeszédablak címének meghatározására használják)data(object)(opcionális objektum, amely különböző kulcsokat tartalmazhat, többek közöttdebug: a fő hibakeresési információ, a hívási veremmel)
Ha hálózati hiba lép fel, akkor a hiba leírása egyszerűen egy objektum
{type: 'network'}. Amikor hálózati hiba történik, egy értesítés jelenik meg, és a szervert rendszeresen megkeresik, amíg nem válaszol. Az értesítés bezárul, amint a szerver válaszol.
Scroller szolgáltatás¶
Áttekintés¶
Technikai név:
scrollerFüggőségek: nincsenek
Amikor a felhasználó rákattint egy horgonyra a web kliensben, ez a szolgáltatás automatikusan a célpontra görget (ha megfelelő).
The service adds an event listener to get click’s on the document. The service checks
if the selector contained in its href attribute is valid to distinguish anchors and Odoo
actions (e.g. <a href="#target_element"></a>). It does nothing if it is not the case.
Egy SCROLLER:ANCHOR_LINK_CLICKED esemény kerül kiváltásra a fő alkalmazás buszon, ha a kattintás úgy tűnik, hogy egy elemre irányul. Az esemény tartalmaz egy egyedi eseményt, amely az element egyezést és annak id-ját referenciaként tartalmazza. Ez lehetővé teheti más részek számára, hogy kezeljék a horgonyokkal kapcsolatos viselkedést. Az eredeti esemény is meg van adva, mivel szükség lehet annak megakadályozására. Ha az eseményt nem akadályozzák meg, akkor a felhasználói felület a cél elemre görget.
API¶
A következő értékek találhatók a fentebb ismertetett anchor-link-clicked egyedi eseményben.
Név |
Típus |
Leírás |
|---|---|---|
|
|
A href által megcélzott horgony elem |
|
|
A href-ben található azonosító |
|
|
Az eredeti kattintási esemény |
Megjegyzés
A görgető szolgáltatás egy SCROLLER:ANCHOR_LINK_CLICKED eseményt bocsát ki a main bus-on. A görgető szolgáltatás alapértelmezett görgetési viselkedésének elkerülése érdekében használja a preventDefault()-ot az eseményen, amelyet a hallgatónak ad, így helyesen megvalósíthatja saját viselkedését a hallgatóból.
Cím Szolgáltatás¶
Áttekintés¶
Technikai név:
titleFüggőségek: nincsenek
The title service offers a simple API that allows to read/modify the document
title. For example, if the current document title is „Odoo”, we can change it
to „Odoo 15 - Apple” by using the following command:
// in some component setup method
const titleService = useService("title");
titleService.setParts({ odoo: "Odoo 15", fruit: "Apple" });
API¶
A title szolgáltatás a következő interfészt kezeli:
interface Parts {
[key: string]: string | null;
}
Minden kulcs a cím egy részének azonosítóját képviseli, és minden érték az a sztring, amely megjelenik, vagy null, ha eltávolították.
Az API-ja a következő:
- current
Ez egy sztring, amely a jelenlegi címet képviseli. A következő módon van felépítve:
value_1 - ... - value_n, ahol mindenvalue_iegy (nem null) érték, amely aPartsobjektumban található (amit agetPartsfüggvény ad vissza).
- getParts()¶
- Visszatérési érték
A jelenlegi
Partsobjektum részei, amelyet a cím szolgáltatás tart fenn
- setParts(parts)¶
- Argumentum
parts (
Parts()) – objektum, amely a szükséges változást képviseli
A
setPartsmetódus lehetővé teszi több címrész hozzáadását/cseréjét/törlését. Egy rész (egy érték) törlése azzal történik, hogy a hozzá tartozó kulcs értékétnull-ra állítjuk.Megjegyzendő, hogy csak egyetlen részt lehet módosítani anélkül, hogy a többi részt érintenénk. Például, ha a cím a következő részekből áll:
{ odoo: "Odoo", action: "Import" }
ahol a
currentértékOdoo - Import, akkorsetParts({ action: null, });
a cím
Odoo-ra változik.
Felhasználói szolgáltatás¶
Áttekintés¶
Technikai név:
userFüggőségek:
rpc
A user szolgáltatás számos adatot és néhány segédfüggvényt biztosít a csatlakoztatott felhasználóval kapcsolatban.
API¶
Név |
Típus |
Leírás |
|---|---|---|
|
|
|
|
|
Információ az adatbázisról |
|
|
A felhasználó kezdőlapjaként használt művelet azonosítója |
|
|
A felhasználó adminisztrátor-e (a |
|
|
A felhasználó része-e a rendszer csoportnak ( |
|
|
használt nyelv |
|
|
A felhasználó neve |
|
|
A felhasználó partner példányának azonosítója |
|
|
A felhasználó időzónája |
|
|
A felhasználó azonosítója |
|
|
A felhasználó alternatív beceneve |
- updateContext(update)¶
- Argumentum
update (
object()) – az objektum, amellyel a kontextust frissíteni kell
frissítse a felhasználói kontextust a megadott objektummal.
userService.updateContext({ isFriend: true })
- removeFromContext(key)¶
- Argumentum
key (
string()) – a célzott attribútum kulcsa
távolítsa el az értéket a megadott kulccsal a felhasználói kontextusból
userService.removeFromContext("isFriend")
- hasGroup(group)¶
- Argumentum
group (
string()) – a keresett csoport xml_id-ja
- Visszatérési érték
Promise<boolean>a felhasználó a csoportban van-e
ellenőrizze, hogy a felhasználó tagja-e egy csoportnak
const isInSalesGroup = await userService.hasGroup("sale.group_sales")