Capacidades comunes
El objeto de contexto expone las capacidades nativas de NocoBase. Algunas solo están disponibles en el Plugin, otras solo en los componentes y otras en ambos lados con sintaxis diferente. Vista general:
A continuación se describen una a una, agrupadas por namespace.
Peticiones API (ctx.api)
Use ctx.api.request() para llamar al backend. Su uso es idéntico al de Axios.
En el Plugin
import { Plugin } from '@nocobase/client-v2';
class MyPlugin extends Plugin {
async load() {
// Petición directa dentro de load()
const response = await this.context.api.request({
url: 'app:getInfo',
method: 'get',
});
console.log('Información de la aplicación', response.data);
}
}
En componentes
import { useFlowContext } from '@nocobase/flow-engine';
export default function MyPage() {
const ctx = useFlowContext();
const handleLoad = async () => {
// Petición GET
const response = await ctx.api.request({
url: 'users:list',
method: 'get',
});
console.log(response.data);
// Petición POST
await ctx.api.request({
url: 'users:create',
method: 'post',
data: { name: 'Tao Tao' },
});
};
return <button onClick={handleLoad}>Cargar datos</button>;
}
Combinado con useRequest de ahooks
En los componentes puede usar useRequest de ahooks para simplificar la gestión del estado de la petición:
import { useFlowContext } from '@nocobase/flow-engine';
import { useRequest } from 'ahooks';
export default function PostList() {
const ctx = useFlowContext();
const { data, loading, error, refresh } = useRequest(() =>
ctx.api.request({
url: 'posts:list',
method: 'get',
}),
);
if (loading) return <div>Cargando...</div>;
if (error) return <div>Error en la petición: {error.message}</div>;
return (
<div>
<button onClick={refresh}>Refrescar</button>
<pre>{JSON.stringify(data?.data, null, 2)}</pre>
</div>
);
}
Interceptores de peticiones
Mediante ctx.api.axios puede añadir interceptores de petición/respuesta, normalmente en el load() del Plugin:
async load() {
// Interceptor de petición: añadir cabecera personalizada
this.context.api.axios.interceptors.request.use((config) => {
config.headers['X-Custom-Header'] = 'my-value';
return config;
});
// Interceptor de respuesta: tratamiento unificado de errores
this.context.api.axios.interceptors.response.use(
(response) => response,
(error) => {
console.error('Error en la petición', error);
return Promise.reject(error);
},
);
}
Cabeceras personalizadas de NocoBase
NocoBase Server admite las siguientes cabeceras personalizadas. Suelen inyectarse automáticamente mediante interceptores y no es necesario establecerlas a mano:
Internacionalización (ctx.t / ctx.i18n)
Los plugins de NocoBase gestionan los archivos multilingües en el directorio src/locale/, y ctx.t() se utiliza para acceder a las traducciones desde el código.
Archivos multilingües
Cree un archivo JSON por idioma bajo src/locale/:
plugin-hello/
└── src/
└── locale/
├── zh-CN.json
└── en-US.json
// zh-CN.json
{
"Hello": "你好",
"Your name is {{name}}": "你的名字是 {{name}}"
}
// en-US.json
{
"Hello": "Hello",
"Your name is {{name}}": "Your name is {{name}}"
}
Atención
La primera vez que añada un archivo de idioma debe reiniciar la aplicación para que surta efecto.
ctx.t()
En los componentes, obtenga textos traducidos con ctx.t():
const ctx = useFlowContext();
// Uso básico
ctx.t('Hello');
// Con variables
ctx.t('Your name is {{name}}', { name: 'NocoBase' });
// Especificar namespace (el por defecto es el nombre del paquete del plugin)
ctx.t('Hello', { ns: '@my-project/plugin-hello' });
this.t()
En el Plugin es más cómodo usar this.t(): inyecta automáticamente el nombre del paquete del plugin como namespace, sin necesidad de pasar ns:
class MyPlugin extends Plugin {
async load() {
// Usa automáticamente el nombre del paquete actual como ns
console.log(this.t('Hello'));
// Equivalente a
console.log(this.context.t('Hello', { ns: '@my-project/plugin-hello' }));
}
}
ctx.i18n
ctx.i18n es la instancia subyacente de i18next. Por lo general basta con ctx.t(). Si necesita cambiar el idioma dinámicamente o escuchar cambios de idioma, use ctx.i18n:
// Idioma actual
const currentLang = ctx.i18n.language; // 'zh-CN'
// Escuchar cambios de idioma
ctx.i18n.on('languageChanged', (lng) => {
console.log('Idioma cambiado a', lng);
});
tExpr()
tExpr() genera una expresión de traducción diferida y suele usarse en FlowModel.define(), ya que el define() se ejecuta al cargar el módulo, momento en el que aún no existe la instancia de i18n:
import { tExpr } from '@nocobase/flow-engine';
HelloBlockModel.define({
label: tExpr('Hello block'), // Genera '{{t("Hello block")}}', se traduce en tiempo de ejecución
});
Para una explicación completa de la internacionalización (archivos de traducción, hook useT, tExpr, etc.), consulte Internacionalización (i18n). La lista completa de códigos de idioma soportados por NocoBase está en Lista de idiomas.
Logger (ctx.logger)
ctx.logger produce logs estructurados y está basado en pino.
En el Plugin
import { Plugin } from '@nocobase/client-v2';
class MyPlugin extends Plugin {
async load() {
this.context.logger.info('Plugin cargado', { plugin: 'my-plugin' });
this.context.logger.error('Error al inicializar', { error });
}
}
En componentes
import { useFlowContext } from '@nocobase/flow-engine';
export default function MyPage() {
const ctx = useFlowContext();
const handleLoad = async () => {
ctx.logger.info('Página cargada', { page: 'UserList' });
ctx.logger.debug('Estado actual del usuario', { user });
};
// ...
}
Niveles de log de mayor a menor: fatal > error > warn > info > debug > trace. Solo se emiten los logs cuyo nivel sea mayor o igual al configurado.
Rutas (ctx.router / ctx.route / ctx.location)
Las capacidades de rutas se dividen en tres bloques: registro (solo en el Plugin), navegación e información (solo en componentes).
Registro de rutas (this.router / this.pluginSettingsManager)
Dentro del load() del Plugin, registre rutas de páginas con this.router.add() y páginas de configuración con this.pluginSettingsManager:
async load() {
// Registrar una ruta de página normal
this.router.add('hello', {
path: '/hello',
componentLoader: () => import('./pages/HelloPage'),
});
// Registrar una página de configuración (aparecerá en el menú "Configuración del plugin")
this.pluginSettingsManager.addMenuItem({
key: 'my-settings',
title: this.t('My Settings'),
icon: 'SettingOutlined', // Iconos de Ant Design, ver https://5x.ant.design/components/icon
});
this.pluginSettingsManager.addPageTabItem({
menuKey: 'my-settings',
key: 'index',
title: this.t('My Settings'),
componentLoader: () => import('./pages/MySettingsPage'),
});
}
Para más detalles, consulte Router. Para un ejemplo completo de página de configuración, consulte Crear una página de configuración del plugin.
Atención
this.router es el RouterManager y se usa para registrar rutas. this.pluginSettingsManager es el PluginSettingsManager y se usa para registrar páginas de configuración. Ninguno de los dos es lo mismo que ctx.router (React Router, que sirve para navegar entre páginas) en los componentes.
Navegación (ctx.router)
En los componentes, use ctx.router.navigate() para navegar:
const ctx = useFlowContext();
ctx.router.navigate('/hello'); // -> /v/hello
En los componentes, obtenga la información de la ruta actual con ctx.route:
const ctx = useFlowContext();
// Parámetros dinámicos (por ejemplo, ruta definida como /users/:id)
const { id } = ctx.route.params;
// Nombre de la ruta
const { name } = ctx.route;
Tipo completo de ctx.route:
interface RouteOptions {
name?: string; // Identificador único de la ruta
path?: string; // Plantilla de la ruta
pathname?: string; // Ruta completa
params?: Record<string, any>; // Parámetros de la ruta
}
URL actual (ctx.location)
ctx.location ofrece la información detallada de la URL actual, similar al window.location del navegador:
const ctx = useFlowContext();
console.log(ctx.location.pathname); // '/v/hello'
console.log(ctx.location.search); // '?page=1'
console.log(ctx.location.hash); // '#section'
Aunque ctx.route y ctx.location son accesibles en el Plugin a través de this.context, durante la carga del plugin la URL aún no es determinista y los valores carecen de sentido. Recomendamos usarlos en los componentes.
Gestión de vistas (ctx.viewer / ctx.view)
ctx.viewer ofrece una API imperativa para abrir diálogos, drawers y otras vistas. Funciona tanto en el Plugin como en los componentes.
En el Plugin
import { Plugin } from '@nocobase/client-v2';
class MyPlugin extends Plugin {
async load() {
// Por ejemplo, abrir un diálogo en una lógica de inicialización
this.context.viewer.dialog({
title: 'Bienvenido',
content: () => <div>Plugin inicializado</div>,
});
}
}
En componentes
import { Button } from 'antd';
import { useFlowContext } from '@nocobase/flow-engine';
export default function MyPage() {
const ctx = useFlowContext();
const openDetail = () => {
// Abrir un diálogo
ctx.viewer.dialog({
title: 'Editar usuario',
content: () => <UserEditForm />,
});
};
const openDrawer = () => {
// Abrir un drawer
ctx.viewer.drawer({
title: 'Detalle',
content: () => <UserDetail />,
});
};
return (
<div>
<Button onClick={openDetail}>Editar</Button>
<Button onClick={openDrawer}>Ver detalle</Button>
</div>
);
}
Método genérico
// Especificar el tipo de vista con type
ctx.viewer.open({
type: 'dialog', // 'dialog' | 'drawer' | 'popover' | 'embed'
title: 'Título',
content: () => <SomeComponent />,
});
Operar dentro de la vista (ctx.view)
Dentro del componente del diálogo o drawer puede manipular la vista actual mediante ctx.view (por ejemplo, cerrarla):
import { Button } from 'antd';
import { useFlowContext } from '@nocobase/flow-engine';
function DialogContent() {
const ctx = useFlowContext();
return (
<div>
<p>Contenido del diálogo</p>
<Button onClick={() => ctx.view.close()}>Cerrar</Button>
</div>
);
}
FlowEngine (this.flowEngine)
this.flowEngine es la instancia de FlowEngine y solo está disponible en el Plugin. Suele utilizarse para registrar FlowModel:
import { Plugin } from '@nocobase/client-v2';
class MyPlugin extends Plugin {
async load() {
// Registrar FlowModel (forma recomendada con carga bajo demanda)
this.flowEngine.registerModelLoaders({
HelloBlockModel: {
loader: () => import('./models/HelloBlockModel'),
},
});
}
}
FlowModel es el núcleo del sistema de configuración visual de NocoBase. Si su componente debe aparecer en los menús "Añadir bloque / campo / acción", debe envolverlo con un FlowModel. Para más detalles, consulte FlowEngine.
Más capacidades
Las siguientes capacidades pueden resultar útiles en escenarios más avanzados:
Para el uso detallado, consulte la Documentación completa de FlowEngine.
Enlaces relacionados