# Ui-bind referencje: każde polecenie, opcja i atrybut

> Wszystkie polecenia ui-bind z tym, co każdy robi, opcje, które kontrolują, kiedy to działa, i atrybuty, które wybierają element docelowy.

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

`<ui-bind>` jest elementem, który stosuje **komandy** do DOM, gdy wartość jego ścieżki się zmienia. ta strona zawiera listę tego, co robi każda polecenie, opcje, które decydują *w momencie, w którym to działa i atrybuty, które wybierają *który element* zmienia.

Format to `config="command:expression;command:expression"`. W wyrażeniu `value` to wartość ścieżki, a `element` (także `el`) to zmieniany element. Polecenie może mieć selektor (`text .name:value` stosuje je do elementów `.name` wewnątrz), a `attr` najpierw bierze nazwę atrybutu (`attr title:value`).

## Polecenia zmieniające element

| Polecenie | Co robi |
|---|---|
| `text:expr` | ustawia tekst; pusta wartość pokazuje tekst `empty` |
| `html:expr` | ustawia wewnętrzny HTML (zrób escape samodzielnie) |
| `value:expr` | ustawia wartość kontrolki formularza |
| `title:expr`, `href:expr`, `src:expr` | ustawia ten atrybut |
| `attr name:expr` | ustawia dowolny atrybut |
| `.class:expr` | dodaje klasę, gdy wyrażenie jest prawdziwe, i usuwa ją, gdy fałszywe |
| `show:expr` / `hide:expr` | dodaje lub usuwa klasę `hidden` |
| `visible:expr` / `invisible:expr` | dodaje lub usuwa klasę `invisible` (element zachowuje swoje miejsce) |
| `checked:expr` | zaznacza lub odznacza `input` wewnątrz |
| `disabled:expr` / `enabled:expr` | wyłącza lub włącza kontrolki wewnątrz (`input`, `select`, `textarea`, `button`) oraz elementy `ui-component` wewnątrz |
| `required:expr` | ustawia opcję `required` elementów `ui-component` wewnątrz (nie dotyka zwykłego `input`) |
| `template` | renderuje szablon Tangular elementu (zobacz przepis o szablonach) |
| `exec:path` / `refresh:path` | wywołuje funkcję pod tą ścieżką z wartością, ścieżką i elementem, przy każdym `SET` ścieżki bindera |

`show` i `hide` uruchamiają się najpierw, potem `visible` i `invisible`, a `text`, `html` i `template` na końcu, aby widoczność elementu była już znana, gdy zapisywana jest zawartość. `text`, `html` i `template` są zapisywane tylko, gdy element jest widoczny, chyba że w tej samej konfiguracji jest `forcerender:true`: wtedy są zapisywane nawet przy ukrytym elemencie.

## Opcje: kiedy uruchamiają się polecenia

| Opcja | Co robi |
|---|---|
| `changes` | pomija aktualizację, gdy wartość jest taka sama jak ostatnia |
| `strict` | uruchamia się tylko, gdy zmieniła się sama ścieżka bindera, a nie ścieżka potomna (`user.name` nie uruchamia bindera `user`) |
| `track:a,b` | uruchamia się tylko, gdy zmieniła się jedna z tych ścieżek (binder `user` śledzący `user.name` ignoruje `user.age`); uruchamia się ponownie przy każdym `SET` śledzonej ścieżki, nawet z tą samą wartością |
| `once` | uruchamia się raz, a potem binder jest usuwany |
| `check:path` | wywołuje funkcję pod tą ścieżką z `(value, path, element)`; polecenia uruchamiają się tylko, gdy zwróci true |
| `delay:ms` | czeka tyle milisekund i renderuje raz, nawet jeśli wartość zmieniła się w tym czasie kilka razy (100, gdy nie podano wartości) |
| `empty:text` | tekst pokazywany zamiast pustej wartości (`---`, gdy nie podano tekstu) |
| `format:pattern` | formatuje wartość `text`, `html`, `value`, `attr`, `title`, `href` i `src` przez `String.format` |
| `class:name` | dodaje tę klasę do elementu `ui-bind` raz, po pierwszym renderowaniu |
| `assign:path` | zapisuje instancję bindera pod tą ścieżką |
| `helpers:path` | obiekt pod tą ścieżką dostarcza pomocników szablonu: z `helpers:hh` i `hh = { shout: fn }` szablon może użyć `{{ value | shout() }}` |

## Atrybuty: który element się zmienia

Domyślnie polecenia zmieniają element `ui-bind`. Te atrybuty wybierają inny:

- `element="#target"` dowolny element strony (selektor jQuery)
- `child=".inner"` element wewnątrz `ui-bind`
- `parent=".card"` najbliższy pasujący przodek

Ścieżka może zaczynać się od `!` (`path="!user.nick"`): binder ignoruje wtedy momenty, gdy wartość to `null` lub `undefined`. Nazwa polecenia może też zaczynać się od `!` lub `~`: prefiks jest akceptowany i ignorowany, polecenie działa jak bez niego.

## Aktywne polecenia

- **Używaj jednego atrybutu na polecenie: `title:value` i `alt:value` zapisz jako dwa polecenia.**

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