# Ui-bind: ogni comando, opzione e attribuzione

> Tutti i comandi di ui-bind con ciò che ciascuno fa, le opzioni che controllano quando si esegue, e gli attributi che scelgono l'elemento mirato.

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

`<ui-bind>` è l'elemento che applica **comandi** al DOM quando il valore del suo percorso cambia.Questa pagina elenca ciò che ogni comando fa, le opzioni che decidono *quando* esce e gli attributi che scelgono *che elemento* cambia

Il formato è `config="command:expression;command:expression"`. In un'espressione `value` è il valore del percorso ed `element` (anche `el`) è l'elemento che viene cambiato. Un comando può avere un selettore (`text .name:value` lo applica agli elementi `.name` interni) e `attr` prende prima il nome dell'attributo (`attr title:value`).

## Comandi che cambiano l'elemento

| Comando | Cosa fa |
|---|---|
| `text:expr` | imposta il testo; un valore vuoto mostra il testo di `empty` |
| `html:expr` | imposta l'HTML interno (fai tu l'escape) |
| `value:expr` | imposta il valore di un controllo di modulo |
| `title:expr`, `href:expr`, `src:expr` | imposta quell'attributo |
| `attr name:expr` | imposta qualsiasi attributo |
| `.class:expr` | aggiunge la classe quando l'espressione è vera e la rimuove quando è falsa |
| `show:expr` / `hide:expr` | aggiunge o rimuove la classe `hidden` |
| `visible:expr` / `invisible:expr` | aggiunge o rimuove la classe `invisible` (l'elemento mantiene il suo spazio) |
| `checked:expr` | spunta o deseleziona l'`input` interno |
| `disabled:expr` / `enabled:expr` | disabilita o abilita i controlli interni (`input`, `select`, `textarea`, `button`) e gli elementi `ui-component` interni |
| `required:expr` | imposta l'opzione `required` degli elementi `ui-component` interni (non tocca un semplice `input`) |
| `template` | renderizza il template Tangular dell'elemento (vedi la ricetta dei template) |
| `exec:path` / `refresh:path` | chiama la funzione a quel percorso con il valore, il percorso e l'elemento, per ogni `SET` del percorso del binder |

`show` e `hide` vengono eseguiti per primi, poi `visible` e `invisible`, e `text`, `html` e `template` per ultimi, così la visibilità dell'elemento è già nota quando il contenuto viene scritto. `text`, `html` e `template` vengono scritti solo finché l'elemento è visibile, a meno che `forcerender:true` sia nella stessa configurazione: allora vengono scritti anche quando l'elemento è nascosto.

## Opzioni: quando i comandi vengono eseguiti

| Opzione | Cosa fa |
|---|---|
| `changes` | salta l'aggiornamento quando il valore è uguale all'ultimo |
| `strict` | viene eseguito solo quando è cambiato il percorso del binder stesso, non quando è cambiato un percorso figlio (`user.name` non esegue un binder di `user`) |
| `track:a,b` | viene eseguito solo quando è cambiato uno di quei percorsi (un binder di `user` che segue `user.name` ignora `user.age`); viene eseguito di nuovo a ogni `SET` di un percorso seguito, anche con lo stesso valore |
| `once` | viene eseguito una volta e poi il binder viene rimosso |
| `check:path` | chiama la funzione a quel percorso con `(value, path, element)`; i comandi vengono eseguiti solo quando restituisce true |
| `delay:ms` | attende quei millisecondi e renderizza una volta, anche se nel frattempo il valore è cambiato più volte (100 quando non viene dato alcun valore) |
| `empty:text` | il testo mostrato al posto di un valore vuoto (`---` quando non viene dato alcun testo) |
| `format:pattern` | formatta il valore di `text`, `html`, `value`, `attr`, `title`, `href` e `src` con `String.format` |
| `class:name` | aggiunge quella classe all'elemento `ui-bind` una volta, dopo il primo rendering |
| `assign:path` | memorizza l'istanza del binder a quel percorso |
| `helpers:path` | l'oggetto a quel percorso fornisce gli helper del template: con `helpers:hh` e `hh = { shout: fn }`, il template può usare `{{ value | shout() }}` |

## Attributi: quale elemento cambia

Per impostazione predefinita i comandi cambiano l'elemento `ui-bind`. Questi attributi ne scelgono un altro:

- `element="#target"` qualsiasi elemento della pagina (un selettore jQuery)
- `child=".inner"` un elemento dentro il `ui-bind`
- `parent=".card"` l'antenato più vicino che corrisponde

Il percorso può iniziare con `!` (`path="!user.nick"`): il binder ignora allora i momenti in cui il valore è `null` o `undefined`. Anche il nome di un comando può iniziare con `!` o `~`: il prefisso viene accettato e ignorato, il comando funziona come senza.

## Attribuzione di comandi

- **Usa un attributo per comando: scrivi `title:value` e `alt:value` come due comandi.**

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