# Trouver et appeler composants et plugins : FIND, COMPONENTS, SETTER, EXE, TAPI, MIDDLEWARE et ADAPT

> Cherchez les composants de la page par nom ou chemin, appelez une méthode de plusieurs composants à la fois, appelez des fonctions par nom, utilisez deux adresses d'API avec TAPI et PIPE, exécutez un middleware avant une route et remplacez les marqueurs d'un texte.

Framework: jcomponent20
Product: jComponent 20 (jcomponent@20)
Language: fr
Content-SHA256: 45bd2bc03336a54b0f74b47cf081f9e443a9b1538723fef8ba148952071ff5ce
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: jcomponent20@3fedd009a277f50fddc608b97afbec553b67c51b
Review: not-recorded

- `FIND(selector, [all])` renvoie un composant prêt : `'notice'` est son **nom**, `'.msg'` son **chemin** (il correspond aux chemins qui le contiennent) et `'#id'` son id ; avec `all` à `true` il renvoie la liste. `COMPONENTS(path)` renvoie la liste des composants prêts dont le chemin est sous `path` ; les drapeaux d'un chemin la filtrent (`'msg @visible'`).
- `SETTER('name/method', a, b, c, d)` appelle `method` de **chaque** composant prêt portant ce nom (`'.path/method'` pour un chemin, `'#id/method'` pour un id, `'*/method'` pour tous). Un nom qui n'est pas encore chargé est d'abord chargé (un composant paresseux). `ASETTER(...)` ne l'appelle pas : il renvoie une fonction qui le fera.
- `EXE(name, a, b, c, d)` (comme `EXEC()`) appelle ce que dit le nom : `'plugin/method'` une méthode d'un plugin, `'function'` une fonction globale, ou un chemin de l'état qui contient une fonction (`'FUNC.save'`). `SEEX(name, value)` est pareil, mais quand le nom n'est pas une fonction il **met** le chemin à `value`.
- `TAPI(name, data, callback)` est `API(DEF.api, ...)` et `PIPE(name, data, callback)` est `API(DEF.pipe, ...)` : deux adresses de points de terminaison que vous définissez une fois dans `DEF.api` et `DEF.pipe`.
- `MIDDLEWARE(name, function(next) {})` enregistre une fonction qui s'exécute avant une route : elle doit appeler `next()` pour la laisser continuer. Une route en demande une (ou plusieurs, séparées par des virgules) comme troisième argument : `ROUTE('/path/', handler, 'name')`. `MIDDLEWARE(['a', 'b'], callback)` exécute les middlewares dans l'ordre puis le callback ; un middleware qui n'appelle pas `next()` arrête la chaîne.
- `NEWUIBIND(element, path, config)` crée un `ui-bind` sur un élément depuis le code (l'élément n'a pas besoin des attributs) et le renvoie.
- `ADAPT(path, id, text)` prépare le texte d'un composant venu de l'extérieur : il traduit `@(...)`, remplace `~PATH~` et `CLASS` par le chemin et `~ID~` par l'id, et met le `path` dans les balises `<ui-plugin>` qui n'en ont pas. `COMPILE` est la même fonction que `NOOP` dans jComponent 20 : elle ne fait rien.
- Les objets derrière tout : `jComponent`, `Total`, `MAIN` et `M` sont le même objet (le moteur : `M.components` est la liste des composants, `M.version` la version), `W` est `window`, `DEF` les valeurs par défaut, et `REPO`, `FUNC`, `TEMP` et `PLUGINS` sont des objets simples à vous : `FUNC` pour les fonctions que `EXE('FUNC.name')` peut appeler, `TEMP` est vidé par jComponent quand la page redémarre.

```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>
```
