Étape 1 sur 1

Afficher et créer une note avec Owl

Cette fois, le navigateur dessine l'écran et dialogue avec l'ORM Odoo pour relire ou créer les mêmes notes.

Un composant Owl vit dans le navigateur, à l'intérieur du client web Odoo. La view reste plus simple pour une fiche classique. Le composant devient intéressant lorsqu'on veut un écran très personnalisé qui se rafraîchit sans recharger toute la page.

Conservez les mêmes noms techniques

Les extraits utilisent title et body. Gardez ces mêmes noms techniques dans le JavaScript et le template Owl.

1. Lecture seule : le service ORM fournit les notes

custom_addons/training_hello/static/src/training_notes/training_notes.js
import { Component, onWillStart, useState } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { useService } from "@web/core/utils/hooks";

export class TrainingNotes extends Component {
    static template = "training_hello.TrainingNotes";

    setup() {
        this.orm = useService("orm");
        this.state = useState({ notes: [] });
        onWillStart(() => this.loadNotes());
    }

    async loadNotes() {
        this.state.notes = await this.orm.searchRead(
            "training.note", [], ["title", "body"]
        );
    }
}

registry.category("actions").add("training_hello.training_notes", TrainingNotes);
custom_addons/training_hello/static/src/training_notes/training_notes.xml
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
  <t t-name="training_hello.TrainingNotes">
    <div class="o_action p-4">
      <h1>Notes de formation</h1>
      <ul>
        <li t-foreach="state.notes" t-as="note" t-key="note.id">
          <strong t-esc="note.title"/>
          <p t-esc="note.body"/>
        </li>
      </ul>
    </div>
  </t>
</templates>

Déclarez les deux fichiers comme assets et reliez le tag enregistré en JavaScript à une client action. Cette action peut être ajoutée au fichier XML qui contient déjà les menus des notes :

custom_addons/training_hello/__manifest__.py · web.assets_backend
"web.assets_backend": [
    # ... les assets existants
    "training_hello/static/src/training_notes/training_notes.js",
    "training_hello/static/src/training_notes/training_notes.xml",
],
custom_addons/training_hello/views/training_note_views.xml · action et menu à ajouter
<record id="training_notes_client_action" model="ir.actions.client">
  <field name="name">Notes Owl</field>
  <field name="tag">training_hello.training_notes</field>
</record>
<menuitem id="training_notes_owl_menu" name="Notes Owl"
          parent="training_note_menu_root"
          action="training_notes_client_action" sequence="30"/>

2. Rendre le composant capable de créer une note

Ajoutez un état pour les valeurs du form, puis appelez le même ORM Odoo. Le navigateur ne choisit aucun accès supplémentaire : orm.create() arrive à Odoo, qui applique les droits du même utilisateur connecté.

training_notes.js · remplacez setup(), puis ajoutez la méthode à la classe
setup() {
    this.orm = useService("orm");
    this.state = useState({ notes: [], title: "", body: "" });
    onWillStart(() => this.loadNotes());
}

async createNote() {
    const title = this.state.title.trim();
    if (!title) {
        return;
    }
    await this.orm.create("training.note", [{
        title,
        body: this.state.body,
    }]);
    this.state.title = "";
    this.state.body = "";
    await this.loadNotes();
}
training_notes.xml · à ajouter avant la liste
<form t-on-submit.prevent="createNote">
  <label>Titre <input t-model="state.title" required="required"/></label>
  <label>Contenu <textarea t-model="state.body"></textarea></label>
  <button type="submit" class="btn btn-primary">Enregistrer</button>
</form>
Trois portes, une même base

La view interne utilise directement les mécanismes standard d'Odoo. Le template QWeb passe par un contrôleur Python. Le composant Owl passe par le service ORM du client web. Dans les trois cas, ce sont le model, l'ACL et l'ORM Odoo qui protègent et enregistrent les données dans PostgreSQL. Le choix concerne l'expérience à construire, pas la permission de contourner les règles.