Internacionalización (i18n)
La validación con @QRule de QuickModel produce mensajes de error como strings. Cuando tu aplicación soporta múltiples idiomas, puedes conectar cualquier librería i18n para traducir esos strings automáticamente — sin cambiar las definiciones de tus modelos.
Cómo funciona
Configura una función resolver en QConfig. Cada vez que una regla falla, QuickModel pasa el mensaje de error crudo (o clave) por el resolver antes de devolverlo al llamante:
import { QConfig } from 'quickmodel';
QConfig.configure({
i18n: {
resolver: (key) => miLibreriaI18n.traducir(key),
},
});El resolver se llama únicamente para reglas que fallan — nunca para las que pasan.
Ejemplo básico
QConfig.configure({
i18n: {
resolver: (key) => t(key), // cualquier función de traducción
},
});
@Quick()
class UserModel extends QModel<IUser> {
@QRule(
(val: string) => val.length >= 3,
'validation.name.minLength' // clave i18n
)
declare name: string;
}
const result = new UserModel({ name: 'Al' }).$qCheckRules();
// → { valid: false, errors: [{ field: 'name', message: 'El nombre debe tener al menos 3 caracteres' }] }
// El resolver tradujo 'validation.name.minLength' para el locale activoIntegración con librerías i18n habituales
vue-i18n
import { createI18n } from 'vue-i18n';
import { QConfig } from 'quickmodel';
const i18n = createI18n({ ... });
QConfig.configure({
i18n: {
resolver: (key) => String(i18n.global.t(key)),
},
});react-i18next
import i18next from 'i18next';
import { QConfig } from 'quickmodel';
QConfig.configure({
i18n: {
resolver: (key) => i18next.t(key),
},
});Angular TranslateService
import { TranslateService } from '@ngx-translate/core';
export function setupQuickModelI18n(translate: TranslateService): void {
QConfig.configure({
i18n: {
resolver: (key) => translate.instant(key),
},
});
}Sin librería — mapa estático
const mensajes: Record<string, string> = {
'validation.name.minLength': 'El nombre debe tener al menos 3 caracteres',
'validation.email.format': 'Formato de email inválido',
};
QConfig.configure({
i18n: {
resolver: (key) => mensajes[key] ?? key, // fallback a la clave si no existe
},
});Estrategia 1 — Claves i18n en @QRule
Almacena claves de traducción en lugar de strings literales. El resolver las traduce en tiempo de ejecución:
@Quick()
class ProductModel extends QModel<IProduct> {
@QRule((v: string) => v.length > 0, 'validation.title.required')
@QRule((v: string) => v.length <= 200, 'validation.title.maxLength')
declare title: string;
@QRule((v: number) => v > 0, 'validation.price.positive')
declare price: number;
}Ventajas: El modelo es completamente agnóstico al locale. Cambiar las traducciones no requiere tocar el modelo.
Estrategia 2 — Resolver lazy () => string en @QRule
Pasa una función en lugar de un string. Se evalúa en el momento de checkRules(), tomando el locale actual:
import { t } from './i18n';
@Quick()
class UserModel extends QModel<IUser> {
@QRule(
(val: string) => val.length >= 3,
() => t('validation.name.minLength') // evaluado en tiempo de validación
)
declare name: string;
}Ventajas: No se necesita resolver global en QConfig.i18n. Funciona cuando distintas partes de la app tienen diferentes contextos de locale.
Estrategia 3 — Combinar ambas
Usa resolvers lazy en @QRule para mensajes de campo específicos, y un resolver global en QConfig.i18n como fallback universal para el resto de claves:
QConfig.configure({
i18n: {
resolver: (key) => t(key), // fallback global para todos los modelos
},
});
@Quick()
class UserModel extends QModel<IUser> {
@QRule(
(val: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val),
() => t('validation.email.format') // lazy, con locale actual
)
declare email: string;
@QRule((v: string) => v.length >= 8, 'validation.password.minLength')
declare password: string; // usa el resolver global vía QConfig
}Patrón de pipe en Angular
En Angular puedes almacenar claves simples y aplicar | translate en los templates — sin resolver global:
@Quick()
class FormModel extends QModel<IFormData> {
@QRule((v: string) => v !== '', 'FORM.NAME_REQUIRED')
declare name: string;
}<!-- Template: traduce la clave devuelta en e.message -->
<span *ngFor="let e of errors">{{ e.message | translate }}</span>Reglas asíncronas e i18n
El resolver también se aplica a los errores de checkRulesAsync():
const result = await model.$qCheckRulesAsync();
// → errors[].message también pasa por el resolverReferencia de API
| Símbolo | Descripción |
|---|---|
QConfig.configure({ i18n: { resolver } }) | Registra un resolver de mensajes global |
resolver(key: string): string | Recibe el mensaje o clave crudo, devuelve el string traducido |
@QRule(pred, 'clave') | Usa una clave string como mensaje de error |
@QRule(pred, () => string) | Función lazy evaluada en tiempo de validación |
Ver también
- Validación — API de
@QRuleycheckRules() - Configuración por clase — sobrescribir configuración por clase de modelo
- Primeros pasos — configuración global
QConfig