You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Render pattern (required for ko-* bindings to activate):
45
+
- Bindings are **strings** evaluated at runtime by `ko.applyBindings(viewModel, element)`
46
+
- Binding-context variables (`$data`, `$parent`, `$index`, `$root`) resolve at runtime
47
+
- No build step needed — works directly in the browser
48
+
- Playground: put HTML in the HTML editor, JS in the TSX editor, run
47
49
48
-
```jsx
50
+
### TSX (ko-*) — compile-time JSX expressions
51
+
52
+
```tsx
53
+
<spanko-text={message} />
54
+
<buttonko-click={handler}>Label</button>
55
+
<ulko-foreach={items}><liko-text="$data" /></ul>
56
+
```
57
+
58
+
-`ko-*` attribute values in `{}` are **JavaScript expressions** evaluated at compile time by esbuild
59
+
- Top-level variables (`message`, `handler`, `items`) must be defined in scope before the JSX
60
+
- Binding-context variables inside `ko-foreach` children (like `$data`, `$parent`) use **string** syntax: `ko-text="$data"` (not `ko-text={$data}`)
61
+
- Requires esbuild JSX transform + `tko.jsx.render()` to produce DOM nodes
62
+
-`ko.applyBindings({}, container)` then activates the `ko-*` bindings on the rendered DOM
63
+
64
+
### Key difference: compile-time vs runtime
65
+
66
+
In HTML, `data-bind="foreach: people"` is a string — knockout evaluates `people` in the view model at runtime.
67
+
68
+
In TSX, `ko-foreach={people}` is a JSX expression — esbuild resolves `people` as a JavaScript variable at compile time. The variable must exist in scope:
69
+
70
+
```tsx
71
+
// Variables must be defined before the JSX expression
72
+
const people =ko.observableArray([...])
73
+
74
+
const view = (
75
+
<ulko-foreach={people}>
76
+
<liko-text="name" /> {/* string — resolved by knockout at runtime */}
Copy file name to clipboardExpand all lines: tko.io/public/agent-testing.md
+57Lines changed: 57 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -70,6 +70,62 @@ Console output appears in `#console-messages` as child elements.
70
70
71
71
esbuild-wasm takes a few seconds to initialize on first load. The playground shows "esbuild ready" in `#esbuild-status` when it's ready. Code auto-runs after compilation.
72
72
73
+
## Option 3: Testing doc page examples
74
+
75
+
The TKO docs at tko.io show code examples as paired HTML + JavaScript blocks. Each pair has:
76
+
-**TSX/HTML tabs** on the HTML block (showing both `ko-*` and `data-bind` syntax)
77
+
-**"Open in Playground" button** on both tabs (opens the example in the playground)
78
+
79
+
### Testing an HTML example from the docs
80
+
81
+
Extract the HTML and JS from the code blocks and use Option 1 (static HTML file):
82
+
83
+
```html
84
+
<!DOCTYPE html>
85
+
<html><body>
86
+
<!-- paste the HTML code block here -->
87
+
<scriptsrc="https://tko.io/lib/tko.js"></script>
88
+
<script>
89
+
window.ko=window.tko
90
+
// paste the JS code block here
91
+
</script>
92
+
</body></html>
93
+
```
94
+
95
+
### Testing a TSX example from the docs
96
+
97
+
TSX examples use `ko-*` attributes which require JSX compilation. Use Option 2 (playground).
98
+
99
+
Important: `ko-*` attribute values in `{braces}` are **compile-time JavaScript expressions**, not runtime binding strings. Variables referenced in `ko-*={expr}` must be defined in the TSX scope before the JSX expression. Binding-context variables inside `ko-foreach` children should use **string syntax**: `ko-text="name"` not `ko-text={name}`.
100
+
101
+
```tsx
102
+
// 1. Define variables that ko-* attributes reference
103
+
const people =ko.observableArray([...])
104
+
105
+
// 2. JSX template using ko-* attributes
106
+
const view = (
107
+
<ulko-foreach={people}>
108
+
<liko-text="$data" />
109
+
</ul>
110
+
)
111
+
112
+
// 3. Render and activate bindings
113
+
const root =document.getElementById('root')
114
+
const { node } =tko.jsx.render(view)
115
+
root.appendChild(node)
116
+
ko.applyBindings({}, root)
117
+
```
118
+
119
+
### Verifying playground links from doc pages
120
+
121
+
Each "Open in Playground" button encodes `{ html, js }` in the URL hash. To verify:
122
+
123
+
1. Navigate to the doc page (e.g., `http://localhost:4321/bindings/foreach-binding/`)
124
+
2. Click "Open in Playground" on the HTML tab
125
+
3. The playground should show the HTML in the HTML editor, JS in the TSX editor
126
+
4. Wait for "esbuild ready", then the preview should render the example
127
+
5. For TSX tab links: the playground currently receives TSX-style HTML — this requires manual restructuring to run (defining variables, wrapping in JSX, using `tko.jsx.render()`)
128
+
73
129
## Which option to use
74
130
75
131
| Scenario | Option |
@@ -78,3 +134,4 @@ esbuild-wasm takes a few seconds to initialize on first load. The playground sho
78
134
| JSX/TSX code |**Option 2** — playground has esbuild-wasm |
79
135
| Quick observable/computed logic test |**Option 1** — no DOM needed, just script |
80
136
| Sharing a runnable example with a human |**Option 2** — give them the playground URL |
137
+
| Verifying doc page examples work |**Option 1** for HTML tab, **Option 2** for TSX tab |
Copy file name to clipboardExpand all lines: tko.io/src/content/docs/bindings/click-binding.md
+58-3Lines changed: 58 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,24 @@ title: Click Binding
8
8
The `click` binding adds an event handler so that your chosen JavaScript function will be invoked when the associated DOM element is clicked. This is most commonly used with elements like `button`, `input`, and `a`, but actually works with any visible DOM element.
9
9
10
10
### Example
11
-
<live-exampleparams='id: "click"'></live-example>
11
+
```html
12
+
<div>
13
+
You've clicked <spandata-bind="text: numberOfClicks"></span> times
Each time you click the button, this will invoke `incrementClickCounter()` on the view model, which in turn changes the view model state, which causes the UI to update.
@@ -30,7 +47,27 @@ Each time you click the button, this will invoke `incrementClickCounter()` on th
30
47
When calling your handler, Knockout will supply the current model value as the first parameter. This is particularly useful if you're rendering
31
48
some UI for each item in a collection, and you need to know which item's UI was clicked. For example,
@@ -45,7 +82,25 @@ Two points to note about this example:
45
82
46
83
In some scenarios, you may need to access the DOM event object associated with your click event. Knockout will pass the event as the second parameter to your function, as in this example:
In this example, the "Your cellphone number" text box will initially be disabled. It will be enabled only when the user checks the box labelled "I have a cellphone".
0 commit comments