# Buscar y llamar componentes y plugins: FIND, COMPONENTS, SETTER, EXE, TAPI, MIDDLEWARE y ADAPT

> Busca los componentes de la página por nombre o ruta, llama a un método de varios componentes a la vez, llama a funciones por nombre, usa dos direcciones de API con TAPI y PIPE, ejecuta middleware antes de una ruta y reemplaza los marcadores de un texto.

Framework: jcomponent20
Product: jComponent 20 (jcomponent@20)
Language: es
Content-SHA256: 7d75285592ecc9e2a1ae34561f3872803e45fc66d32e97002daaec1746801aa9
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: jcomponent20@3fedd009a277f50fddc608b97afbec553b67c51b
Review: not-recorded

- `FIND(selector, [all])` devuelve un componente que está listo: `'notice'` es su **nombre**, `'.msg'` su **ruta** (coincide con las rutas que lo contienen) y `'#id'` su id; con `all` en `true` devuelve la lista. `COMPONENTS(path)` devuelve la lista de componentes listos cuya ruta está bajo `path`; las banderas de una ruta la filtran (`'msg @visible'`).
- `SETTER('name/method', a, b, c, d)` llama a `method` de **cada** componente listo con ese nombre (`'.path/method'` para una ruta, `'#id/method'` para un id, `'*/method'` para todos). Un nombre que aún no está cargado se carga primero (un componente perezoso). `ASETTER(...)` no lo llama: devuelve una función que lo hará.
- `EXE(name, a, b, c, d)` (igual que `EXEC()`) llama a lo que dice el nombre: `'plugin/method'` un método de un plugin, `'function'` una función global, o una ruta del estado que contiene una función (`'FUNC.save'`). `SEEX(name, value)` es igual, pero cuando el nombre no es una función **pone** la ruta a `value`.
- `TAPI(name, data, callback)` es `API(DEF.api, ...)` y `PIPE(name, data, callback)` es `API(DEF.pipe, ...)`: dos direcciones de endpoints que se establecen una vez en `DEF.api` y `DEF.pipe`.
- `MIDDLEWARE(name, function(next) {})` registra una función que se ejecuta antes de una ruta: tiene que llamar a `next()` para dejarla seguir. Una ruta pide una (o más, separadas por comas) como tercer argumento: `ROUTE('/path/', handler, 'name')`. `MIDDLEWARE(['a', 'b'], callback)` ejecuta los middleware en orden y luego el callback; uno que no llame a `next()` detiene la cadena.
- `NEWUIBIND(element, path, config)` crea un `ui-bind` en un elemento desde el código (el elemento no necesita los atributos) y lo devuelve.
- `ADAPT(path, id, text)` prepara el texto de un componente que viene de fuera: traduce `@(...)`, reemplaza `~PATH~` y `CLASS` por la ruta y `~ID~` por el id, y pone el `path` en las etiquetas `<ui-plugin>` que no lo tienen. `COMPILE` es la misma función que `NOOP` en jComponent 20: no hace nada.
- Los objetos detrás de todo: `jComponent`, `Total`, `MAIN` y `M` son el mismo objeto (el motor: `M.components` es la lista de componentes, `M.version` la versión), `W` es `window`, `DEF` los valores por defecto, y `REPO`, `FUNC`, `TEMP` y `PLUGINS` son objetos simples tuyos: `FUNC` para funciones que `EXE('FUNC.name')` puede llamar, `TEMP` lo vacía jComponent cuando la página vuelve a empezar.

```js definitions/math.js
NEWACTION('Math/add', {
	name: 'Add two numbers',
	input: '*a:Number, *b:Number',
	action: function($, model) {
		$.callback({ sum: model.a + model.b });
	}
});
```

```js controllers/api.js
exports.install = function() {
	ROUTE('API /api/ +math_add --> Math/add');
	ROUTE('API /pipe/ +math_add --> Math/add');
};
```

```html public/index.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title>jComponent</title>
	<link rel="stylesheet" href="//cdn.componentator.com/spa.min@20.css" />
	<script src="//cdn.componentator.com/spa.min@20.js"></script>
</head>
<body>
	<ui-component name="notice" path="msg"></ui-component>
	<ui-component name="notice" path="other"></ui-component>
	<ui-plugin path="shop"></ui-plugin>
	<p id="target">x</p>
	<script>

		COMPONENT('notice', function(self) {
			self.make = function() { self.element.html('<b></b>'); };
			self.say = function(text, extra) { self.find('b').text(text + (extra || '')); };
		});

		PLUGIN('shop', function(exports) {
			exports.hello = function(a) { window.shoplog = 'hello ' + a; };
		});

		window.globalfn = function(a, b) { window.globallog = [a, b]; };
		FUNC.local = function(a) { window.funclog = a; };

		DEF.api = '/api/';
		DEF.pipe = '/pipe/';

	</script>
</body>
</html>
```
