¿CÓMO CREAR UN OWL MIXIN EN ODOO 18?
En el mundo de la programación, la reutilización del código es extremadamente importante, no sólo para el desarrollador actual sino también para cualquiera que trabaje en el proyecto en el futuro. Una estructura de código limpia y reutilizable ahorra tiempo, reduce errores y facilita mucho el desarrollo.
Aquí es exactamente donde los Mixins se vuelven útiles. Un mixin es simplemente un fragmento de código reutilizable —como una función o variable— que puedes agregar fácilmente a cualquier componente OWL (Odoo Web Library).
La anatomía de los Mixins en Owl.js
Un Mixin en Owl.js es simplemente una función que toma un componente y devuelve un nuevo componente con características adicionales. Actúa como una capa complementaria que puedes adjuntar a cualquier componente sin volver a reescribir la misma lógica.
Un mixin generalmente contiene tres partes principales:
1. La función Mixin Un mixin siempre comienza como una función normal de JavaScript:
JavaScript
export function TimerMixin(BaseComponent) {
// Cuerpo de la función
}
- TimerMixin: Nombre del mixin.
- BaseComponent: El componente que desea ampliar.
Esto hace que el mixin sea flexible; puedes aplicarlo a cualquier componente.
2. Devolver una clase extendida Dentro del mixin, devolvemos una nueva clase que extiende el componente dado:
JavaScript
return class extends BaseComponent {
// características adicionales aquí
}
Esto significa:
- El componente original mantiene toda su lógica.
- El mixin añade un comportamiento extra además.
- El componente final se convierte en una versión "combinada".
3. Agregar lógica reutilizable La clase devuelta contiene lógica reutilizable como métodos, estados o servicios:
JavaScript
setup() {
super.setup();
this.startTime = Date.now();
}
getElapsedTime() {
return Date.now() - this.startTime;
}
Todo lo escrito en el interior estará disponible para todos los componentes que utilicen este mixin.
Veamos un ejemplo: Un TimerMixin reutilizable
Este código define el módulo del mixin:
JavaScript
/** @odoo-module **/
export function TimerMixin(BaseComponent) {
return class extends BaseComponent {
setup() {
super.setup();
this.startTime = null;
this.endTime = null;
}
startTimer() {
this.startTime = Date.now();
console.log("Temporizador iniciado");
}
stopTimer() {
this.endTime = Date.now();
const diff = this.endTime - this.startTime;
console.log("Temporizador detenido:", diff, "ms");
return diff;
}
};
}
Qué hace este mixin: Este TimerMixin da a cualquier componente OWL la capacidad de:
- Iniciar un temporizador.
- Detener un temporizador.
- Calcular cuánto tiempo tardó algo.
Cómo funciona esto:
- export function TimerMixin(BaseComponent): El mixin es una función que recibe un componente existente.
- return class extends BaseComponent: Crea un nuevo componente con funciones adicionales.
- setup() { super.setup(); ... }: Mantiene la configuración original y agrega nuevas variables (startTime, endTime).
Aplicando el Mixin
En este componente, el mixin se aplica envolviendo el componente base con TimerMixin. Esto significa que el componente recibe automáticamente todos los métodos adicionales definidos en el mixin, como startTimer() y stopTimer().
Cuando el componente se carga, simplemente llama a estos métodos como si fueran suyos.
JavaScript
/** @odoo-module **/
import { Component, onMounted } from "@odoo/owl";
import { TimerMixin } from "./timer_mixin";
class BaseDemoComponent extends Component {
static template = "DemoTimerComponent";
}
// Aplicar el mixin al componente
export class DemoComponent extends TimerMixin(BaseDemoComponent) {
setup() {
super.setup();
// Iniciar temporizador en el montaje
onMounted(() => {
this.startTimer();
setTimeout(() => {
const time = this.stopTimer();
console.log("Tiempo empleado:", time, "ms");
}, 1500);
});
}
}
Aquí puede ver que el componente utiliza con éxito los métodos del mixin para iniciar y detener el temporizador, y el tiempo de ejecución final se imprime en la consola, mostrando cómo funciona la lógica del mixin en acción real.
Plantilla de demostración (XML)
Para visualizar esto, necesitamos una plantilla simple:
XML
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<t t-name="DemoTimerComponent">
<div class="alert alert-info mt-3">
Demostración de mixin de temporizador cargada — ¡consulte los registros de la consola!
</div>
</t>
</templates>
Para que nuestro componente de demostración esté disponible en el entorno web de Odoo, lo registramos en el registro main_components (o el que corresponda a su caso de uso). Esto le dice a Odoo que nuestro componente debe cargarse automáticamente.
JavaScript
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { DemoComponent } from "./demo_component";
registry.category("main_components").add("demo_timer_component", {
Component: DemoComponent,
});
Configuración del Manifiesto (__manifest__.py)
Asegúrese de que todos los archivos JavaScript y XML necesarios (archivo mixin, archivo de componente de demostración, plantillas) se agreguen correctamente al manifiesto de su módulo.
Nota: Este ejemplo asume que se está implementando dentro de un módulo que depende de point_of_sale, pero la lógica aplica para cualquier módulo web.
Python
{
'name': "Pos Purchase Limit",
'version': '1.0',
'depends': ['base', 'point_of_sale'],
'application': True,
'auto_install': False,
'installable': True,
'website': 'www.cybrosys.com',
'data': [
'views/pos_purchase_limit_views.xml',
'views/pos_settings_purchase_limit.xml',
],
'assets': {
'point_of_sale._assets_pos': [
'odoo_mixin_example/static/src/js/timer_mixin.js',
'odoo_mixin_example/static/src/js/demo_component.js',
'odoo_mixin_example/static/src/js/demo_mount.js',
'odoo_mixin_example/static/src/xml/demo_template.xml',
]
},
}
Conclusión
Este es un pequeño ejemplo, pero puedes aplicar el mismo concepto de Mixin a cualquier componente OWL en Odoo. Los Mixins te ayudan a mantener tu código limpio, reutilizable y modular. En lugar de reescribir la misma lógica una y otra vez, simplemente adjunta el mixin y el componente obtiene instantáneamente nueva funcionalidad. Es una forma eficiente y escalable de estructurar su código frontend de Odoo.