Introducción a Ractive.js


Por:
Johann Paul Echavarría Zapata
@abrupto
23 de abril de 2014 
@MedellinJS,  @Ruta_n
  • Creado por Rich Harris @Rich_Harris
  • Periodista interactivo y frontend developer de uno de los periódicos más importantes del mundo: The Guardian.
  • Requiere creación de notas interactivas en poco tiempo.

Problemática a resolver 


  • Templating
  • Manipulación eficiente del dom
  • Databinding
  • Disminuir complejidad
  • Mejorar legibilidad del código y la mantenibilidad

ejemplo

<p>Hola Pedro! Tienes 4 nuevos mensajes</p>
¿Cómo actualizar este html si tienes un modelo con los datos en javascript?

  • Recargar la página como en el siglo pasado y actualizar el número desde el server (horrible).
  • Manipular el contenido con javascript puro (vanilla) o con una librería como jQuery, Dojo, Mootols. (Problemas)
  • Usar template y reemplazar datos en JSON
    • <p>Hola {{ usuario }} tienes {{ nroMensajes}} nuevos mensajes.</p>
  • Este es mejor, pero cuando se actualiza toda la vista ¿Qué pasa? 

opciones

Frameworks completos
Ember.js
Angular.js
Frameworks livianos
Backbone.js
Librerías de templating
Mustache.js
Underscore.js
Handlebars.js
Ractive.js

Tutoriales

Introducción y configuración en 60 segundos:

Tutorial interactivo:

Handlebars.js vs Ractive.js

Característica Handlebars Ractive
Condicionales e iteradores
Expresiones usando helpers
Partials (subplantillas)
Expresiones directas
Eventos
Doble databinding
Extender y reutilizar clases
Animaciones
Transiciones
Integracion SVG ✔* ✔*

Forma de crear plantilla

        <script type="x-cualquiercosa diferente a text/javascript">
        <p>{{greeting}} {{recipient}}!</p>  /*Mustaches pueden usarse en attributos y en cualquier parte del html*/
        </script>

    Instanciación y parseo:

    var ractive = new Ractive({
      el: output,
      template: template,
      data: { greeting: 'Hello', recipient: 'world' }
    })

Two-way binding

<label>Enter your name: <input value='{{name}}'></label>
<p>Hello, {{name}}!</p>

<script>
var ractive = new Ractive({
  el: output,
  template: template
});
</script>

condicionales e iteradores

Son el mismo mustache y tiene en cuenta la definición de valores "falsy" en JS (ECMA):

  1. false
  2. null
  3. undefined
  4. NaN
  5. ""
  6. 0

Todo lo demás es true.
Esto puede verificarse usando la doble negación: !!variable

Condicional (no usa #if ni else)

        {{#username}}
            <p>Hola {{#username}}</p>
        {{/username}}

 {{^username}}
            <p>Por favor inicia sesión</p>
{{/username}} 

    var ractive = new Ractive({
      el: idElemento,
      template: idPlantilla,
      data: { username: 'Hello', recipient: 'world' }
    })

Ciclos, iteraciones

          <table class='superheroes'>
             <tr><th>Superhero name</th>
                <th>Real name</th>
                <th>Superpower</th></tr>
{{#superheroes}}
                <tr>
                  <td><a href='{{info}}'>{{name}}</a></td>
                  <td>{{realname}}</td>
                  <td>{{power}}</td>
                </tr>
              {{/superheroes}}
            </table>

Manipulación de datos en modelo de forma reactiva

Agregar
        xmen[ xmen.length ] = newSuperhero;
            ractive.update( 'superheroes' );
        
        Más simple:
            xmen.push( newSuperhero );
        
        Del mismo modo puede usarse otros métodos de JS como los de  Array.prototype:
            push, pop, shift, unshift, splice, sort and reverse

Modificación de mustache específico

        ractive.set( 'greeting', 'Bonjour' );

        Otra forma acumulando:

        ractive.set( 'counter', ractive.get( 'counter' ) + 1 )

        Otra para valores numéricos: 

        ractive.add( 'counter' );
        ractive.subtract('counter')
ractive.animate() (en atributos css)

Variables anidadas

Con punto se accede jerárquicamente, hijos, nietos etc.
    {{country.climate.temperature}}  

Con ../ se accede al padre y ../../ al abuelo

    Modificación: 
ractive.set( 'country.climate.temperature', 'hot' );

Expresiones

        {{ format(population) }}
         format es un método de la propiedad data
      data: {
        country: 'the UK',
        population: 62641000,
        format: function ( num ) {
          if ( num > 1000000000 ) return ( num / 1000000000 ).toFixed( 1 ) + ' billion';
          if ( num > 1000000 ) return ( num / 1000000 ).toFixed( 1 ) + ' million';
          if ( num > 1000 ) return ( Math.floor( num / 1000 ) ) + ',' + ( num % 1000 );
          return num;
        }

Expresiones con método y con operación matemática

<td>{{ format( price * quantity ) }}</td>

Eventos (similar a jquery)

<button on-click='activate'>Activate!</button>

      Subscripción al evento:

           ractive.on( 'activate', function ( event ) {
        //Código del evento
        alert( 'Activating!' );
        });

Subscripción múltiples eventos

        <button on-click='activate'>Activate!</button>
        <button on-click='deactivate'>Deactivate!</button>

        ractive.on({
          activate: function () {
            alert( 'Activating!' );
          },
          deactivate: function () {
            alert( 'Deactivating!' );
          }
        });

Acumular multiples handlers al mismo evento


        ractive.on( 'activate', function () {
          alert( 'activate 1!' );
        });        
        ractive.on( 'activate', function () {
          alert( 'activate 2!' );
        }); 

Desuscribir evento(Como en jquery)

ractive.off( 'select', selectHandler );
ractive.off( 'select' ); // unsubscribes ALL 'select' handlers
           OTRA FORMA:
                var listener = ractive.on( 'select', selectHandler );

                var otherListeners = ractive.on({
                  activate: function () { alert( 'Activating' ); },
                  deactivate: function () { alert( 'Deactivating!' ); }
                });

                listener.cancel();
                otherListeners.cancel()

Eliminar toda la vista del dom

 ractive.teardown()

Eventos personalizados (custom events)

<button on-tap='activate'>Activate!</button>  

Tab se considera superior a clic por que no se activa cuando toma mucho tiempo entre el down y el up
        mousedown-mouseup
        touchstart-touchend

Manipulación de arreglos en propiedad data:

 Dos notaciones:
  1. ractive.set( 'user[0]', name )
  2. ractive.set( 'user.0', name )

Transiciones

Los atributos intro y outro definen el efecto de transición o easing:

<div 
intro='fade' 
outro='fly' 
class='large button' 
on-tap='show:2'>

Click me!

</div>

Triple mustache

Código de Editor de html

No escapa el html
   <script id='myTemplate' type='text/ractive'>
        <textarea value="{{htmltext}}"></textarea>
<div>
{{{htmltext}}}
<div>
    </script>    
    
    <script src='Ractive.0.3.9.min.js'></script>

PARTIALS

<ul class='todos'>
  {{#items:i}}
    {{>item}}
  {{/items}}
</ul>

Extender clase Ractive


Evento init: Se define como método de la clase que se extiende y se ejecuta una vez la plantilla se haya procesado.

SVG


¡GRACIAS!


Introducción a Ractive.js

By Johann Paul Echavarria Zapata

Introducción a Ractive.js

  • 2,140