# référence ui-bind : chaque commande, option et attribut

> Toutes les commandes de ui-bind avec ce que chacune fait, les options qui contrôlent le moment de son exécution et les attributs qui choisissent l'élément cible.

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

`<ui-bind>` est l'élément qui applique des **commandes** au DOM lorsque la valeur de son chemin change. Cette page répertorie ce que fait chaque commande, les options qui décident *quand* elle s'exécute et les attributs qui choisissent *quel élément* elle change.

Le format est `config="command:expression;command:expression"`. Dans une expression, `value` est la valeur du chemin et `element` (également `el`) est l'élément modifié. Une commande peut avoir un sélecteur (`text .name:value` l'applique aux éléments `.name` à l'intérieur) et `attr` prend en premier le nom de l'attribut (`attr title:value`).

## Commandes qui changent l'élément

| Commande | Ce qu'il fait |
|---|---|
| `text:expr` | définit le texte; une valeur vide affiche le texte `empty` |
| `html:expr` | définit le code HTML interne (échappez-le vous-même) |
| `value:expr` | définit la valeur d'un contrôle de formulaire |
| `title:expr`, `href:expr`, `src:expr` | définit cet attribut |
| `attr name:expr` | définit n'importe quel attribut |
| `.class:expr` | ajoute la classe lorsque l'expression est vraie et la supprime lorsqu'elle est fausse |
| `show:expr` / `hide:expr` | ajoute ou supprime la classe `hidden` |
| `visible:expr` / `invisible:expr` | ajoute ou supprime la classe `invisible` (l'élément garde son espace) |
| `checked:expr` | coche ou décoche le `input` à l'intérieur |
| `disabled:expr` / `enabled:expr` | désactive ou active les commandes à l'intérieur (`input`, `select`, `textarea`, `button`) et les éléments `ui-component` à l'intérieur |
| `required:expr` | définit l'option `required` des éléments `ui-component` à l'intérieur (elle ne touche pas un `input` simple) |
| `template` | restitue le modèle Tangular de l'élément (voir la recette du modèle) |
| `exec:path` / `refresh:path` | appelle la fonction sur ce chemin avec la valeur, le chemin et l'élément, pour chaque `SET` du chemin du classeur |

`show` et `hide` s'exécutent en premier, puis `visible` et `invisible`, et `text`, `html` et `template` s'exécutent en dernier, de sorte que la visibilité de l'élément est déjà connue lorsque le contenu est écrit. `text`, `html` et `template` ne sont écrits que lorsque l'élément est visible, sauf si `forcerender:true` est dans la même configuration : alors ils sont écrits même lorsque l'élément est masqué.

## Options : lorsque les commandes sont exécutées

| Options | Ce qu'il fait |
|---|---|
| `changes` | ignore la mise à jour lorsque la valeur est la même que la dernière |
| `strict` | s'exécute uniquement lorsque le chemin du classeur lui-même a changé, pas lorsqu'un chemin enfant a changé (`user.name` n'exécute pas un classeur de `user`) |
| `track:a,b` | ne s'exécute que lorsque l'un de ces chemins a changé (un classeur de `user` qui suit `user.name` ignore `user.age`) ; il s'exécute à nouveau pour chaque `SET` d'un chemin suivi, même avec la même valeur |
| `once` | s'exécute une fois, puis le classeur est supprimé |
| `check:path` | appelle la fonction sur ce chemin avec `(value, path, element)` ; les commandes ne s'exécutent que lorsqu'elles renvoient true |
| `delay:ms` | attend autant de millisecondes et effectue un rendu une fois, même si la valeur a changé plusieurs fois entre-temps (100 lorsqu'aucune valeur n'est donnée) |
| `empty:text` | le texte affiché à la place d'une valeur vide (`---` lorsqu'aucun texte n'est donné) |
| `format:pattern` | formate la valeur de `text`, `html`, `value`, `attr`, `title`, `href` et `src` avec `String.format` |
| `class:name` | ajoute cette classe à l'élément `ui-bind` une fois, après le premier rendu |
| `assign:path` | stocke l'instance de classeur sur ce chemin |
| `helpers:path` | l'objet sur ce chemin fournit les assistants du modèle : avec `helpers:hh` et `hh = { shout: fn }`, le modèle peut utiliser `{{ value | shout() }}` |

## Attributs : quel élément change

Par défaut, les commandes modifient l'élément `ui-bind`. Ces attributs en choisissent un autre :

- `element="#target"` n'importe quel élément de la page (un sélecteur jQuery)
- `child=".inner"` un élément à l'intérieur du `ui-bind`
- `parent=".card"` l'ancêtre le plus proche qui correspond

Le chemin peut commencer par `!` (`path="!user.nick"`) : le classeur ignore alors les instants où la valeur est `null` ou `undefined`. Un nom de commande peut également commencer par `!` ou `~` : le préfixe est accepté et ignoré, la commande fonctionne comme sans lui.

## Commandes d'attribut

- **Utilisez un attribut par commande : écrivez `title:value` et `alt:value` comme deux commandes.**

```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-bind path="user.age" config="visible:value > 17" id="visible"><span>adult</span></ui-bind>
	<ui-bind path="user.age" config="invisible:value > 17" id="invisible"><span>minor</span></ui-bind>
	<ui-bind path="user.name" config="text:value;class:marked" id="classonce"></ui-bind>
	<ui-bind path="user.name" config="text:(window.counter_changes = (window.counter_changes || 0) + 1) && value;changes" id="changes"></ui-bind>
	<ui-bind path="user" config="text:(window.counter_strict = (window.counter_strict || 0) + 1);strict" id="strict"></ui-bind>
	<ui-bind path="user" config="text:value.name;track:user.name" id="track"></ui-bind>
	<ui-bind path="user.name" config="text:value;once" id="once"></ui-bind>
	<ui-bind path="user.name" config="text:value;check:isready" id="check"></ui-bind>
	<ui-bind path="user.name" config="exec:onname" id="exec"></ui-bind>
	<ui-bind path="user.name" config="text:value;assign:binders.main" id="assign"></ui-bind>
	<ui-bind path="!user.nick" config="text:value" id="notnull"></ui-bind>
	<ui-bind path="user.name" config="text:value" element="#target" id="element"></ui-bind>
	<div id="target"></div>
	<ui-bind path="user.name" config="text:value" child=".inner" id="child"><b class="inner"></b></ui-bind>
	<ui-bind path="user.name" config="text .a:value;text .b:value.toUpperCase()" id="selector"><i class="a"></i><i class="b"></i></ui-bind>
	<ui-bind path="user.name" config="show:false;text:value;forcerender:true" id="force"></ui-bind>
	<ui-bind path="user.name" config="show:false;text:value" id="noforce"></ui-bind>
	<ui-bind path="user.admin" config="required:value;disabled:!value" id="flags"><input type="text" /></ui-bind>
	<ui-bind path="user.admin" config="checked:value" id="checked"><input type="checkbox" /></ui-bind>

	<ui-bind path="user.name" config="title+alt:value" id="clone"></ui-bind>
	<ui-bind path="user" config="text:(window.counter_track = (window.counter_track || 0) + 1);track:user.name" id="track2"></ui-bind>
	<ui-bind path="user.name" config="template;helpers:hh" id="helpers"><script type="text/html"><b>{{ value | shout() }}</b></script></ui-bind>
	<ui-bind path="user.none" config="text:value;empty" id="emptydef"></ui-bind>
	<ui-bind path="user.name" config="focus"><input type="text" id="f1" /></ui-bind>
	<ui-bind path="user.name" config="!text:value" id="bang"></ui-bind>
	<ui-bind path="user.name" config="~text:value" id="tilde"></ui-bind>
	<ui-bind path="user.name" config="text:el.attr('id') + '/' + element.attr('id')" id="elvar"></ui-bind>
	<div class="card"><ui-bind path="user.name" config="attr data-n:value" parent=".card" id="parentbind"></ui-bind></div>

	<script>
		window.hh = { shout: s => String(s).toUpperCase() };
		window.isready = function(value, path, element) {
			return value !== 'blocked';
		};
		window.exec_log = [];
		window.onname = function() {
			window.exec_log.push(Array.prototype.slice.call(arguments).map(a => typeof a === 'object' ? (a && a.nodeType ? 'element' : a && a.path ? 'path' : 'object') : String(a)).join('|'));
		};
		SET('user', { name: 'Ann', age: 30, admin: false });
	</script>

</body>
</html>
```
