API · Tags personnalisés

Montage

riot.mount(customTagSelector, [opts])

Le sélecteur customTagSelector sélectionne les éléments correspondants dans la page et vient les monter avec un tag personnalisé. Le nom des éléments sélectionnés doit correspondre au nom du tag personnalisé.

L’objet optionnel opts est passé en paramètre aux tags. Il peut s’agir de n’importe quoi, d’un simple objet à l’API de toute une application. Ou encore d’un store Flux. Cela dépend vraiment de la manière dont vous voulez structurer votre application côté client. Plus d’infos sur les applications Rito modulaires ici.

// selectionne et monte tous les tags <pricing> sur la page
var tags = riot.mount('pricing')

// monte tous les tags personnalisés avec une classe .customer
var tags = riot.mount('.customer')

// monte tous les tags <account> et passe un objet API en option
var tags = riot.mount('account', api)

@returns - retourne la liste des instances de tags montées

Note: les utilisateurs de la compilation sur navigateur auront à insérer les appels à riot.mount dans le callback de riot.compile afin d’obtenir les instances de tag retournées. Sans cela, les appels à riot.mount retourneront undefined.

<script>
riot.compile(function() {
  // here tags are compiled and riot.mount works synchronously
  var tags = riot.mount('*')
})
</script>

riot.mount(‘*’, [opts])

Un sélecteur spécifique à Riot pouvant être utilisé pour monter tous les tags personnalisés de la page:

riot.mount('*')

@returns - retourne la liste des instances de tags montées

riot.mount(selector, tagName, [opts])

Paramètres:

// monte le tag personnalisé "my-tag" sur div#main et passe l'objet api en option
var tags = riot.mount('div#main', 'my-tag', api)

@returns - retourne la liste des instances de tags montées

riot.mount(domNode, tagName, [opts])

Monte un tag personnalisé nommé tagName sur le noeud domNode en passant des données optionnelles avec opts. Par exemple:

// monte le tag personnalisé "users" sur le noeud #slide avec l'objet api en options
riot.mount(document.getElementById('slide'), 'users', api)

@returns - retourne la liste des instances de tags montées

Interprétation du tag

riot.render(tagName, [opts])

Interprète un tag en HTML. Cette méthode est disponible uniquement côté serveur (Node/io.js). Par exemple:

// interprète le tag  "my-tag" en html
var mytag = require('my-tag')
riot.render(mytag, { foo: 'bar' })

@returns - retourne le résultat HTML du tag interprété

Instance de tag

Les propriétés suivantes sont attribuées à chaque instance de tag:

Vous pouvez utiliser ces références à la fois dans le code HTML et JavaScript. Par exemple:

<my-tag>
  <h3>{ opts.title }</h3>

  var title = opts.title
</my-tag>

Vous pouvez librement assigner n’importe quelles données à l’instance (aussi appelé “contexte”) et ces données seront disponibles dans les expressions HTML. Par exemple:

<my-tag>
  <h3>{ title }</h3>

  this.title = opts.title
</my-tag>

Note: si vous avez des variables globales, vous pouvez aussi utiliser ces références dans le code HTML ou JavaScript de vos tags:

window.someGlobalVariable = 'Hello!'
<my-tag>
  <h3>{ someGlobalVariable }</h3>

  var message = someGlobalVariable
</my-tag>

Mise à jour

this.update()

Met à jour toutes les expressions de l’instance courante de tag ainsi que de celles des tags enfants. Cette méthode est automatiquement appelée à chaque fois qu’un gestionnaire d’événements est appelé quand l’utilisateur interagit avec l’application.

Autrement, Riot ne met pas à jour l’UI automatiquement donc vous avez besoin d’appeler cette méthode manuellement. Cela arrive typiquement avec certains événements non reliés à l’interface utilisateur: timeouts, appels AJAX ou événements serveur. Par exemple:

<my-tag>

  <input name="username" onblur={ validate }>
  <span class="tooltip" show={ error }>{ error }</span>

  var self = this

  validate() {
    $.get('/validate/username/' + this.username.value)
      .fail(function(error_message) {
        self.error = error_message
        self.update()
      })
  }
</my-tag>

Dans l’exemple ci-dessus, le message d’erreur est affiché à l’utilisateur une fois la méthode update() appelé. Nous assignons this à self puisqu’à l’intérieur du callback AJAX la variable this pointe sur l’objet réponse et non sur l’instance de tag.

this.update(data)

Affecte les données passées à l’instance courante de tag et met à jour les expressions. C’est la même chose que this.update() mais cela vous permet de passer des données de contexte au passage. Donc au lieu d’écrire ceci:

self.error = error_message
self.update()

vous pouvez faire:

self.update({ error: error_message })

ce qui est plus concis et plus propre.

riot.update()

Met à jour tous les tags montés et leurs expressions sur la page.

@returns - retourne la liste des instances de tags montées sur la page

Démontage

this.unmount(keepTheParent)

Détache le tag et ses enfants de la page. Un événement unmount est déclenché. Si vous voulez démonter un tag sans supprimer le tag parent, vous devez passer le booléen true à la méthode unmount

Supprime le tag du DOM:

mytag.unmount()

Supprime les noeuds enfant du tag et conserve uniquement le tag parent:

mytag.unmount(true)

Tags imbriqués

Vous avez accès aux instances de tags imbriqués via la variable tags:

<my-tag>

  <child></child>

  // accès au tag enfant child
  var child = this.tags.child

</my-tag>

S’il y a plus d’un tag enfant child, on y accède à travers une liste this.tags.child[n]

Vous pouvez également utiliser l’attribut name pour donner un autre nom au tag imbriqué.

<my-tag>

  <child name="mon_tag_imbrique"></child>

  // accès au tag enfant
  var child = this.tags.mon_tag_imbrique

</my-tag>

Les tags enfant sont initialisés après le tag parent afin que les méthodes et propriétés soient disponible lors de l’événement “mount”.

<my-tag>

  <child name="mon_tag_imbrique"></child>

  // accès aux méthodes du tag enfant
  this.on('mount', function() {
    this.tags.mon_tag_imbrique.uneMethode()
  })

</my-tag>

Injection de HTML imbriqué

Le tag <yield> est une fonctionné spéciale au coeur de Riot vous permettant d’injecter et de compiler le contenu de n’importe quel tag personnalisé à l’intérieur de son template au moment de l’exécution. Cette technique vous permet d’étendre les templates de vos tags avec du contenu HTML éventuellement produit par le serveur.

Par exemple, en utilisant le tag suivant my-post

<my-post>
  <h1>{ opts.title }</h1>
  <yield/>
  this.id = 666
</my-post>

chaque fois que vous voulez inclure le tag <my-post> dans votre application

<my-post title="Quel superbe titre">
  <p id="my-content-{ id }">Mon magnifique post est juste formidable</p>
</my-post>

une fois monté avec riot.mount('my-post') , il sera interprété comme ceci:

<my-post>
  <h1>Quel superbe titre</h1>
  <p id="my-content-666">Mon magnifique post est juste formidable</p>
</my-post>

Multi-Transclusion

>=2.3.12

Le tag <yield> fournit également un mécanisme d’emplacements qui vous permet d’injecter du contenu HTML à des endroits spécifiques dans le template.

Par exemple, en utilisant ce tag riot my-other-post :

<my-other-post>
  <article>
    <h1>{ opts.title }</h1>
    <h2><yield from="summary"/></h2>
    <div>
      <yield from="content"/>
    </div>
  </article>
</my-other-post>

chaque fois que vous incluerez le tag <my-other-post> dans votre application

<my-other-post title="Quel superbe titre">
  <yield to="summary">
    Mon magnifique post est juste formidable
  </yield>
  <yield to="content">
    <p>Et le paragraphe qui suit décrit à quel point il est bien</p>
    <p>Très</p>
  </yield>
</my-other-post>

une fois monté avec riot.mount('my-other-post') il sera rendu de cette manière:

<my-other-post>
  <article>
    <h1>Quel superbe titre</h1>
    <h2>Mon magnifique post est juste formidable</h2>
    <div>
      <p>Et le paragraphe qui suit décrit à quel point il est bien</p>
          <p>Très</p>
    </div>
  </article>
</my-other-post>

Injection et boucles

Le tag <yield> peut également être utilisé au sein d’une boucle ou d’un tag enfant mais vous devez être conscient qu’il sera toujours interprété et compilé avec les données du contexte de l’enfant

Le composant riot suivant blog.tag

<blog>
  <h1>{ title }</h1>
  <my-post each={ posts }>
    <a href={ this.parent.backToHome }>Retour à l'accueil</a>
    <div onclick={ this.parent.deleteAllPosts }>Supprimer tous les posts</div>
  </my-post>

  this.backToHome = '/homepage'
  this.title = 'Mon titre de blog'

  this.posts = [
    { title: "post 1", description: 'ma description de post' },
    { title: "post 2", description: 'ma description de post' }
  ]

  // l'instruction bind est nécessaire ici pour préserver le contexte parent
  // dans les tags enfant
  deleteAllPosts() {
    this.posts = []

    // nous devons déclencher manuellement la fonction update
    // car la fonction est déclenchée depuis un tag enfant
    // et ne remonte pas automatiquement la chaîne
    this.update()
  }.bind(this)

</blog>

<my-post>
  <h2>{ title }</h2>
  <p>{ description }</p>
  <yield/>
</my-post>

sera compilé comme ceci:

<blog>
  <h1>Mon titre de blog</h1>
  <my-post>
    <h2>post 1</h2>
    <p>ma description de post</p>
    <a href="/homepage">Retour à l'accueil</a>
    <div>Supprimer tous les posts</div>
  </my-post>
  <my-post>
    <h2>post 2</h2>
    <p>ma description de post</p>
    <a href="/homepage">Retour à l'accueil</a>
    <div>Supprimer tous les posts</div>
  </my-post>
</blog>

Mixins

this.mixin(mixinObject)

Étend le tag actuel avec les fonctionnalités de l’objet mixinObject. Par exemple:

var OptsMixin = {
  // la méthode init est une méthode spéciale invoquée
  // automatiquement quand un tag est étendu avec ce mixin
  // elle n'est pas accessible ensuite depuis le tag étendu
  init: function() {
    this.on('updated', function() { console.log('Updated!') })
  },

  getOpts: function() {
    return this.opts
  },

  setOpts: function(opts, update) {
    this.opts = opts
    if (!update) this.update()
    return this
  }
}

<my-tag>
  <h1>{ opts.title }</h1>

  this.mixin(OptsMixin)
</my-tag>

riot.mixin(mixinName, mixinObject)

Enregistre un mixin partagé, accessible globalement pour être utilisé sur n’importe quel tag: this.mixin(mixinName).

riot.mixin(mixinObject)

Enregistre un mixin global, ajouté automatiquement à toutes les instances de tag.

Evénements

Chaque instance de tag est observable donc vous pouvez utiliser les méthodes on et one pour réagir aux événements survenant sur l’instance de tag. Voici une liste des événements supportés:

Par exemple:

// nettoie les ressources une fois que le tag ne fait plus partie du DOM
this.on('unmount', function() {
  clearTimeout(timer)
})

Mots réservés

La liste suivante de noms de méthodes et de propriétés sont réservés par les tags Riot. Ne les utilisez pas comme variables ou noms de méthodes: opts, parent, tags, root, update, unmount, on, off, one et trigger. Les variables commençant par un underscore (comme this._item) sont également réservés pour l’usage interne. Les variables locales peuvent être librement nommées. Par exemple:

<my-tag>

  // autorisé
  function update() { } 

  // non autorisé
  this.update = function() { }

  // non autorisé
  update() {

  }

</my-tag>

Construction manuelle

riot.tag(tagName, html, [css], [attrs], [constructor])

Crée un nouveau tag personnalisé “manuellement” sans le compilateur.

Exemple

riot.tag('timer',
  '<p>Secondes écoulées: { time }</p>',
  'timer { display: block; border: 2px }',
  'class="tic-toc"',
  function (opts) {
    var self = this
    this.time = opts.start || 0

    this.tick = function () {
      self.update({ time: ++self.time })
    }

    var timer = setInterval(this.tick, 1000)

    this.on('unmount', function () {
      clearInterval(timer)
    })

  })

Voir la démo timer et la doc API de riot.tag pour plus de détails sur les limitations.

Attention en utilisant riot.tag vous ne profiterez pas des avantages du compilateur et les fonctionnalités suivantes ne seront pas disponibles:

  1. Balises auto-fermantes
  2. Expressions sans guillemets. Ecrivez value="{ val }" au lieu de value={ val }
  3. Attributs booléens. Ecrivez __checked="{ flag }" au lieu de checked={ flag }
  4. Ecriture ES6 raccourcie pour les méthodes
  5. <img src={ src }> doit être écrit <img riot-src={ src }> pour éviter des requêtes serveur incorrectes
  6. style="color: { color }" doit être écrit riot-style="color: { color }" afin que les expressions en attributs de style fonctionnent sur Internet Explorer
  7. Précompilation des CSS scopés

Vous pouvez utiliser les tags <template> ou <script> tags comme ceci:

<script type="tmpl" id="my_tmpl">
  <h3>{ opts.hello }</h3>
  <p>et un paragraphe</p>
</script>

<script>
riot.tag('tag-name', my_tmpl.innerHTML, function(opts) {

})
</script>

riot.Tag(impl, conf, innerHTML)

expérimental

Dans riot v2.3, nous avons donné accès au constructeur interne Tag afin de vous permettre de créer des tags personnalisés par des moyens plus créatifs.

Par exemple, en utilisant ES2015:


class MyTag extends riot.Tag {
  constructor(el) {
    super({ tmpl: MyTag.template() }, { root: el })
    this.msg = 'hello'
  }
  bye() {
    this.msg = 'goodbye'
  }
  static template() {
    return `<p onclick="{ bye }">{ msg }</p>`
  }
}

new MyTag(document.getElementById('my-div')).mount()

Il n’est pas recommandé d’utiliser la méthode riot.Tag. Vous devriez l’utiliser seulement si vous avez besoin de certaines fonctionnalités non disponibles via les méthodes précédentes.