A slideshow keeps its index in an attribute.
export default class extends Controller {
static targets = [ "slide" ]
static values = { index: Number }
next() { this.indexValue++ }
previous() { this.indexValue-- }
indexValueChanged() {
this.slideTargets.forEach((el, i) =>
el.hidden = i !== this.indexValue)
}
}
static values maps this.indexValue to the attribute data-slideshow-index-value, typed as a Number. Writing the property writes the attribute. And indexValueChanged() runs on connect and every time the attribute changes, from anywhere.
Press the arrows and watch the attribute. Then edit the attribute directly, as you would in the inspector, and watch the slideshow follow.
Because the HTML is what survives.
Turbo caches pages as HTML. Turbo restores pages as HTML. The server renders HTML. If the slideshow's index lived in a JavaScript variable, every one of those would reset it to zero. In an attribute, the server can set the starting slide, a cached page comes back on the slide you left, and a stream can change it by sending a new attribute.
Defaults live in the definition, so the attribute is optional:
static values = {
index: { type: Number, default: 0 },
effect: { type: String, default: "kenburns" }
}
Try the effect value on the right: set it to kenburns and the slides get a zoom; set it to anything else and they don't. The controller only reads this.effectValue.
Classes and params: same idea, different jobs.
<!-- the CSS class name is data, not code -->
<div data-controller="clipboard"
data-clipboard-supported-class="clipboard--supported">
static classes = [ "supported" ]
this.element.classList.add(this.supportedClass)
<!-- per-button data rides along with the action -->
<button data-action="item#upvote"
data-item-id-param="12345"
data-item-url-param="/votes">
upvote({ params: { id, url } }) { … }
Classes keep CSS names out of your JavaScript. Params let one controller serve many buttons without a target per button. Params are typed like values: numbers, booleans and JSON objects come through parsed. Classes are just strings.