6. Javascript

6.1. Sintaxis

6.1.1. Formato del archivo

  • .js
  • .min.js para versiones “comprimidas” (eliminando espacios y tabulaciones). Aplicaciones como “Koala” crean estas versiones más ligeras a partir de los “.js”.

6.1.2. Software necesario

  • Editor de código
  • Navegador web con JavaScript habilitado

6.1.3. Estructura del código

  • Si se introduce el código dentro de un archivo HTML o PHP,
    deben añadirse las etiquetas de inicio y cierre (Es importante que las etiquetas <script> se encuentren al final del código, para que las referencias a los elementos HTML funcionen. Esto no es necesario si el código Javascript está configurado para ejecutarse en el momento adecuado, usando JQuery por ejemplo)
    <script> … </script>
  • Cada sentencia se termina con punto y coma
  • Se usan llaves para los bloques

6.1.4. Variables

  • Se pueden declarar e iniciar por separado
    var x;
    x = 5;
    var z = 5;
    var x, y;

6.1.5. Mostrar texto

  • console.logconsole.log(“Muestra el texto en la consola”);
  • document.write
    • No añade una nueva línea automáticamente
      document.write(“Hola Mundo”);
      document.write(x);
  • innerHTML(HTML DOM).innerHTML=”Hola Mundo”;
  • alertalert(“Ventana pop-up simple”);
  • confirmconfirm(“Ventana pop-up con opción de aceptar o cancelar”);
  • promptprompt(“Ventana pop-up para ingresar texto”);
  • Concatenación con +: document.write(“Hola “ + x);
  • Concatena también con: var str = <<string>>.concat(<<string>>)

6.1.6. Arrays

  • Permiten almacenar varios valores en la misma variable
    var arr = []; var arrx = [2, 5];
  • Índices empiezan en cero
    document.write(arrx[1]); => 5
  • Cómo añadir elementos
    arr[0] = 4;
    • Al principio: arr.unshift(“Hola”);
    • Al final: arr.push(“Mundo”);
  • Eliminar elementos
    • Al principio: arr.shift();
    • Al final: arr.pop();
    • Otra posición: arr.splice(index_start, num_remove, new_elements);
  • <<array>>.length: indica la longitud de un array.
  • <<array>>.indexOf(item): indica cual es el primer índice en el que aparece el item en el array. Si no aparece, devuelve -1.
  • <<array>>.map(function(item){...}): ejecuta una función en cada uno de los componentes de un array y devuelve otro array con los resultados.
  • <<array>>.filter(funcion): filtra los elementos de un array según una función devuelva "true" o "false". Devuelve otro array.
    • La función que hace de argumento sigue esta estructura:
      function filtro (item, [index, array]){...}
  • <<array>>.sort(): Ordena los elementos de un array de forma alfabética. Para ordenar de otros modos, se inserta una función como la siguiente, que determina el orden según la función devuelva un número mayor o menor que cero (si la resta da negativo, entiende que a.prop es menor que b.prop):
     arr.sort(function(a, b){return a.prop - b.prop})
arr.sort((a,b) => (a.text > b.text) ? 1 : -1);

  • <<array>>.concat([<<array>>]): permite concatenar o crear una copia de un array, ya que, por ejemplo, arr2 = arr1 crea una referencia, no una copia (arr2 = arr1.concat()crea una copia de arr1)
  • new Set(<<array>>): crea un conjunto de valores únicos.
  • Array.from(<<set>>): convierte un Set a Array.

6.1.7. Operadores

  • Aritméticos
    + - * / %
  • Booleanos
    ==
    === (mismo valor y mismo tipo)
    !=
    !== (el valor o el tipo no coinciden)
    <
    <=
    >
    >=
  • Otros
    &&
    ||

6.1.8. Condicionales

  • If
    if(x == 3){
        document.write(“Correcto”);
    }
  • Else if y Else
    if (x <= 4){
        alert(“Good”);
    }else if (x <= 10){
        alert(“Ok”);
    }else{
        alert(“Bad”);
    }
  • Condicional ternario
    var x = (a == b)? <<expresión si verdadero>>:<<expresión si falso>>;
  • Switch
    switch (x){
        case 1:
            alert(“Falso”);
            break;
        case 2:
            alert(“Verdadero”);
            break;
        default:
            alert(“Cualquier otro caso”);
            break;
    }

6.1.9. Bucles

  • For
    for (var i = 0; i < x.length; i++){
        x[i].style.color=”blue”;
    }
  • For in
    • bucles para objetos o arrays (no recomendado en arrays).
      let obj = {a:1, b:2};
      for (let x in obj){
      console.log(x);
      }
      let arr = [2, 4];
      for (let i in arr){
      console.log(arr[i]);
      }
  • forEach
    function ejecutaFuncion(item, [index], [arr]){
        console.log(item);
    }
    var arr = [1, 2];
    arr.forEach(ejecutaFuncion);
    arr.forEach(function(item){console.log(item);});
  • While
    while (x){
        alert(“x existe”);
    }
  • Break
    • Interrumpe el bucle por completo
      while( … ){
      if ( … ){
          break;
      }
      ….
      }
  • Continue
    • Salta una parte del bucle

6.1.10. Funciones

  • Definición
    function mifuncion(){     alert(“Hola Mundo”); }
    function mifuncion(x, y){     alert(x + “ “ + y); }
    • Usando consctructores
      var x = new Function(arg1, arg2, body);
  • Llamar a la función:
    • mifuncion(“Hola”, “Mundo”);
    • setInterval(“funcion”, 1000); (tiempo en milisegundos). Los parámetros de la función se escriben después de los milisegundos, no dentro de la función.
      • clearInterval(variable que contiene setInterval())
    • setTimeout(function(){<<funcion>>}, 2000); (tiempo al término del cual empieza a ejecutarse la función)
  • This
    • "this" es un parámetro que se puede incluir en una función para hacer referencia a:
      • Un objeto si la función se llama de la siguiente manera: objeto.funcion();
      • Un nuevo objeto si se llama a la función con el prefijo "new"
      • Si se usa el método call() o apply(), al parámetro de dichos métodos
      • El objeto global si se hace una llamada simple, tipo funcion()

6.1.11. Clases (ES6) y objetos

  • Definición de una clase (con “class”, en ES6)
class Clase{
constructor(edad = 15, genero = 'hombre'){
this.edad = edad;
this.genero = genero;
alert("Iniciado");
}
muestra(texto){
return texto;
}
}

class MiClase extends Clase {
constructor(edad, genero = 'mujer'){
super(edad, genero);
}
metodo(){
super.metodosuperclase();
}
}

Se puede usar "static" para métodos estáticos, pero no existen las propiedades estáticas.

  • Definición de una clase (con “function”)
function User(name) {
this.name = name;
}
User.prototype.sayHi = function() {
alert(this.name);
}
  • Definición de un objeto (sin clase)
var objeto = {propiedad: ”valor”, propiedad2:“valor2”}; 
  • Nuevo objeto (desde una clase ES6)
 var objeto = new miClase(); 
  • Acceder a una propiedad: objeto.propiedad; (o new miClase().propiedad)
  • Eliminar una propiedad: delete objeto.propiedad
  • Acceder a un método: objeto.funcion();
  • var obj2 = obj1 crea una referencia, no una copia. Para crear copias usa Object.assign()

6.2. ECMAScript 6

6.2.1. Introducción

  • Es el nuevo estándar en Javascript desde 2015.
  • Otros nombres que lo denominan son "Harmony" y ES2015

6.2.2. Novedades

  • let: prefijo para declarar variables restringidas a un bloque (delimitado por llaves {}), por ejemplo dentro de un “if”. Esto evita problemas con "var", ya que "var" se puede restringir local (a nivel de función) o globalmente, pero no a nivel de bloque.
    if(...){
        let x = 5;
    }
  • const: prefijo para declarar constantes restringidas a un bloque.
  • Template literals: simplifica la concatenación de strings. Se denota con ` `. Preserva los cambios de línea, por lo que no es necesario usar \n.
    let str = `Hola ${variable}`;
  • Destructuring: permite asignar elementos de un array o un objeto a diferentes variables de una forma simple:
    let puntos = [4, 6];
    let [x, y] = puntos;
    let obj = {prop:'valor', prop2:'valor2'};
    let {prop, prop2} = obj;
  • Atajos: simplifican la declaración de propiedades (cuando se les asigna una variable con el mismo nombre) y métodos de objetos.
    let tipo = 'valor';
    let obj = {tipo} //similar a '{tipo:tipo}'
    let obj = {metodo(){...}} //similar a {metodo = function(){...}}
  • for of: bucles para arrays, strings, map,... Permite el uso de continue y break.
    let arr = [1, 2];
    for (let x of arr){
        console.log(x);
    }
  • Método abreviado para construir funciones ("arrow notation" o "arrow functions").
    • Solo se puede usar si se asigna a una variable, se pasa como argumento de una función o se asigna a la propiedad de un objeto. Si solo hay una expresión en el cuerpo de la función, no es necesario incluir return:
      var x = (arg1, arg2) => {
      var sum = arg1 + arg2;
      return sum;
      }
      var x = arg => console.log(arg);
      var x = () => alert("Hi");
      arr.forEach(v => {
      console.log(v*2);
      });
    • NOTA: Uso de "this" en las "arrow functions": mientras en una función regular, el valor de this depende de como se llame a la función (con "new", como método de un objeto, con "call()" o "apply()" o con una llamada simple), en las "arrow functions" depende del contexto alrededor de la función
  • Operador spread (...): "extiende" un array en sus elementos. Ayuda a concatenar.
    let arr = [7,8];
    let arr2 = [8,0];
    console.log(...arr,...arr2);
  • Parámetro Resto (...): engloba elementos en un "paquete". Sirve para indicar en las funciones que el número de argumentos es variable. También ayuda a asignar valores de un array.
    function myFunction(arr, ...nums){
        for (let x of nums){
            …
        }
    }
    let arr = [5,7,8,9];
    let [x, ...items] = arr; //x = 5, items = [7,8,9];
  • Parámetros por defecto: indican valores por defecto para los parámetros de una función (se aplican si no aparecen al llamar a la función)
    function myFunction(a, b=2){
        …
    }
    function mifuncion ({prop = 'valor', prop2 = 'valor2'} = {}) {...}

6.3. Selectores, eventos, propiedades y métodos

6.3.1. Selectores

  • document.getElementById(“id”)
  • document.getElementsByTagName(“p”)[] (los corchetes son para concretar la etiqueta, se usan números según el orden en el que aparecen las etiquetas, empezando por el cero)
  • document.getElementsByClassName(“clase”)[]
  • Se pueden usar los dos selectores anteriores juntos
  • document.querySelectorAll(“p.clase”) (permite usar selectores CSS)
  • document.querySelector(“p.clase”) (selecciona solo el primero de los que cumplen el criterio)
  • document.forms
  • objeto.childNodes[]
  • objeto.parentElement

6.3.2. Eventos

  • click
  • change: se activa cuando un <input> se actualiza y pierde el foco.
  • input: se activa cuando un <input> se actualiza.
  • mouseover
  • focus
  • focusout: se activa cuando el elemento pierde el foco.
  • keyup
  • keydown

6.3.3. Propiedades y métodos

  • objeto.innerHTML: para acceder al contenido de una etiqueta HTML
  • objeto.value: para acceder al valor de un <input> por ejemplo
  • objeto.style.propiedad_css (la propiedad se escribirá sin guiones y con la primera letra de la segunda palabra, si la hubiera, en mayúscula)
  • objeto.setAttribute("atributo", "valor")
  • objeto.appendChild()
  • objeto.childElementCount
  • objeto.length: muestra la longitud de un string o un array.
  • Object.keys(objeto): para acceder a los nombres de las propiedades de un objeto (retorna un array)
  • texto.toLowerCase(): transforma texto en minúscula
  • objeto.addEventListener("evento", function(){})
    • Estos eventos pueden aplicarse directamente en el HTML como una propiedad (añadiendo "on" al principio: <button onclick="funcion()">Entrar</button>)
  • window.addEventListener("popstate", function(){}): permite capturar el botón atrás del navegador para simular varias páginas en "aplicaciones de una única página" (SPA). Para que el navegador crea que hay varias páginas, hay que utilizar previamente el método history.pushState() descrito más abajo.
  • método para guardar el valor de una variable durante una iteración (a través de "funciones invocadas al momento"):
    cat_div.addEventListener("click",(function(nameCopy){     return function(){         clicks(nameCopy);     } })(name));
  • window.innerWidth: muestra el ancho de la ventana.
  • objeto.checked: indica si un objeto de tipo "checkbox" está seleccionado o no.
  • objeto.appendChild()
  • objeto.replaceChild()
  • objeto.getAttribute(“atributo”)
  • objeto.setAttribute(“atributo”, “valor”)
  • objeto.hasAttribute(“atributo”)
  • objeto.removeAttribute(“atributo”)
  • objeto.hasChildNodes()
  • objeto.insertBefore()
  • location.reload(recarga la página)
  • location.assign(“direccion”): dirige a una nueva página o a una parte de ella
  • history.pushState(state, title, url): permite cambiar la url que aparece en el navegador para simular una página distinta en "aplicaciones de una única página" (SPA). Puede ser más práctico usar enlaces con parámetros directamente (ver siguiente método).
    history.pushState(null, null, url + "?lib");
    • (definiendo url como document.URL, o como la url de la página principal para que no haya problemas al usar una "query", por ejemplo: test.com?p=1)
  • var urlParams = new URLSearchParams(window.location.search): permite hacer operaciones con los parámetros de una URL (por ejemplo: ?id=4)
    • urlParams.has("parametro"): true si la url contiene el parámetro.
    • urlParams.get("parametro"): da el valor del parámetro.
    • Puede usarse para aplicaciones SPA usando una función intermedia que dirija a las funciones adecuadas según haya o no parámetros en la URL y su valor.
  • window.scrollTo(x,y): hace un "scroll"
  • window.scrollX: indica cuánto scroll horizontal se ha hecho
  • window.scrollY: junto con los anteriores, permite que se recuerde en que posición se encontraba el usuario (guardando el scroll en una variable y ejecutando scrollTo con esa variable)
  • objeto.substr(origen, final): recorta una cadena de texto desde un índice origen hasta un índice final
  • body.onload: permite ejecutar código justo después de que la página se cargue
  • var x = texto.split(“ “): permite crear un array a través de una cadena de texto, separando según se indique en el argumento de la función (en este caso, se separa por los<br>espacios)
  • var str = <array>>.join(<<separador>>): permite unir los elementos de un array para convertirlos en un string, usando el separador indicado.
  • str = str.replace(busca, sustitucion): busca un valor en un texto y lo reemplaza con lo indicado. Para que sustituya todas las ocurrencias hay que usar expresiones regulares (con el modificador g): str.replace(/%20/g, "-")
  • encodeURI(<<url>>) / encodeURIComponent(<<url>>): codifica una URI (identificador de recursos uniforme), cambiando caracteres especiales por compatibles (por ejemplo: tildes, $, ?,<br>“, …). La diferencia entre encodeURI y encodeURIComponent es que el primero no codifica los siguientes caracteres: , / ? : @ & = + $ #
  • parseInt(<<numero>>)
  • parseFloat(<<numero>>)
  • Math.<<método>>
    • Math.random(): devuelve un número aleatorio entre 0 y 1.
    • Math.max(<<num>>,<<num>>): establece el máximo entre dos números.
    • Math.round(<<num>>): redondea.
    • Math.floor(): redondea por lo bajo.
      var arr = ["valor1", "valor2", "valor3"]; var ind_aleatorio = Math.floor(Math.random() * arr.length); console.log(arr[ind_aleatorio]);
    • Math.sqrt(<<num>>): calcula la raíz cuadrada.
  • <<texto>>.link(<<url>>): permite crear etiquetas <a> fácilmente, con la URL y el texto interior.
  • var d = new Date(): crea un objeto de tipo "Date". Los métodos y propiedades de este objeto son:
    • var d = new Date(año, mes, día, hora, minutos, segundos, milisegundos)
    • var d = new Date("2018-01-01")
    • d.getFullYear(): devuelve el año con cuatro dígitos.
    • d.getMonth(): devuelve el mes de 0 a 11.
    • d.setFullYear(2020): establece el año del objeto en 2020.
    • d.toString()

6.3.4. Manejar archivos con FileReader

<input type="file" onchange="showTable(event)"/>
<script>
function showTable(event){
var input = event.target;
var reader = new FileReader();
reader.onload = function(){
var dataURL = reader.result;
var obj = JSON.parse(dataURL);
...
}
reader.readAsText(input.files[0]); }
</script>

6.4. MVC (Model-View-Controller)

6.4.1. Introducción

  • El MVC es un sistema para organizar el código de un programa. Se separan los datos (modelo) de los elementos gráficos con los que interactúa el usuario (vista), con una parte (controlador) que comunica las dos anteriores.
  • Una forma de hacer estas separaciones es a través de objetos Javascript.

6.4.2. Model (modelo)

  • En el modelo se encuentran los datos. Los datos pueden encontrarse en diferentes soportes: objetos Javascript, "localStorage", archivos JSON, SQL, etc.

6.4.3. Controller (controlador)

  • El controlador sirve de intermediario entre el modelo y la vista, ejecuta las operaciones sobre los datos que necesita la vista.
  • Se crea un método "init" (de inicio) que será el que inicie el programa, ejecutando los distintos "init" de la vista

6.4.4. View (vista)

  • En la vista se recogen las interacciones del usuario con la aplicación y se ejecuta la función del controlador adecuada.
  • Se suelen crear varias vistas para partes diferenciadas de la aplicación.
  • Dentro de cada vista suelen crearse dos funciones o métodos: uno que inicia las variables que se van a usar (init) y otro que ejecuta las acciones necesarias y las muestra en la aplicación (render). Esto permite que solo se declaren las variables una vez mientras se pueda actualizar la vista siempre que sea necesario.

6.5. JQuery

6.5.1. Introducción

  • Es la librería más popular de Javascript. Permite simplificar muchas tareas.
  • Se añade al código de la siguiente manera (usar la versión más reciente):
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  • En el código, se hace la referencia a JQuery a través del símbolo "$" seguido de unos argumentos o métodos.
  • Se suele usar el siguiente código al principio del script para evitar que se ejecute antes de que se cargue la página:
    $(function(){
        …
    });
  • También se puede usar:
    $(document).ready(function(){
        …
    });
  • La lista completa de métodos está en http://api.jquery.com/.

6.5.2. Selectores

  • $(“p”)
  • $("<p></p>"): crea un elemento
  • $(“#id”)
  • $(“.clase”)
  • $(“p.clase”)
  • $(“*”)
  • S("#id").prev(): selecciona el elemento anterior al indicado, se puede especificar el tipo buscado.
  • $("#id").parent(): selecciona el elemento inmediatamente superior (un nivel)
  • $("#id").parents(".padre"): selecciona uno de los padres del elemento (varios niveles hacia arriba). No es obligatorio indicar el padre.
  • $("#id").children([<<elemento>>]): selecciona los hijos (un nivel)
  • $("#id").find("#hijos"): busca hijos en varios niveles. Para buscar todos, usa "*".
  • $("#id").siblings(): busca elementos con el mismo padre
  • $(this): puede usarse en bucles con ".each" o dentro de funciones de eventos, para hacer referencia al elemento al que se le aplica el evento.
  • $(“p:first”): primer elemento <p>
  • $(ul li:first-child”): primer elemento <li> de todos los <ul>
  • $(“[atributo]”)
  • $(“input[type=’text’]”)
  • $(“input[type!=’text’]”)
  • $(“tr:even”): selecciona los elementos <tr> pares
  • $(“tr:odd”): elementos <tr> impares

6.5.3. Eventos

  • $(“p”).on(“accion”, function(){}): es el método primario para añadir eventos. Permite añadir varios eventos al mismo objeto. Dentro de la función se puede declarar un argumento "event" (function(e){...}) que permite, entre otras cosas, decirle al navegador que no ejecute la acción por defecto (en etiquetas <a>, por ejemplo) con e.preventDefault(). También permite, con e.target, hacer referencia al objeto del evento.
  • $(“p”).click()
  • $(“p”).dblclick()
  • $(“p”).mouseenter()
  • $(“p”).mouseleave()
  • $(“p”).mousedown(): cuando un botón del ratón es pretado
  • $(“p”).mouseup()
  • $(“p”).keyup(): cuando se deja de pretar una tecla, adecuado para búsquedas que se ejecutan en el momento.
  • $(“p”).hover(): contiene dos funciones, una para cuando el cursor entra y otra para cuando sale
  • $(“p”).focus(): para campos de texto
  • $(“p”).blur(): para cuando pierde el foco

6.5.4. Efectos

  • $(“p”).hide([milisegundos]): también admite slow o fast (en lugar de los milisegundos). Aplica un display:none.
  • $(“p”).show([milisegundos])
  • $(“p”).toggle([milisegundos]): aplica un "hide" y un "show" alternativamente cada vez que se ejecuta.
  • $(“p”).fadeIn([milisegundos])
  • $(“p”).fadeOut([milisegundos])
  • $(“p”).fadeToggle([milisegundos])
  • $(“p”).fadeTo([milisegundos], [opacidad])
  • $(“p”).slideDown([milisegundos])
  • $(“p”).slideUp([milisegundos])
  • $(“p”).slideToggle([milisegundos])
  • $(“p”).animate({parametro_css: ‘valor’}, [milisegundos]): los parámetros compuestos (padding-left) se escriben sin guión y con la primera letra de la segunda palabra en mayúscula (paddingLeft)
  • $(“p”).stop(): detiene una animación
  • A los efectos se les puede añadir como segundo argumento un “callback” o función que se ejecuta tras terminar la animación
  • Se pueden encadenar las animaciones

6.5.5. Métodos

  • $.funcion(): método para incluir funciones que no forman parte de un objeto (getJSON, etc.)
  • $.get(url, function(data){...}): hace una petición a una url y permite trabajar con la respuesta.
  • $.getJSON(url, function(data){...})
  • objeto.text()
  • objeto.html(): incluye etiquetas HTML
  • objeto.val(): para campos de texto
  • objeto.each(function([index],[element]{...}): ejecuta una función en cada elemento de un conjunto. Se puede usar this para referirse al elemento.
  • objeto.attr(“atributo”, [“valor”])
    • También pueden añadirse varias propiedades como un objeto Javascript. En este caso el nombre de las propiedades puede no estar entrecomillado.
  • objeto.append(): inserta contenido al final del elemento
  • objeto.prepend(): inserta contenido al principio del elemento
  • objeto.after(): inserta contenido justo después del elemento
  • objeto.before(): inserta contenido justo antes del elemento
  • appendprependafter y before admiten varios argumentos (contenidos)
  • objeto.remove(): admite un argumento para filtrar con selectores css
  • objeto.empty(): elimina los elementos hijos del seleccionado
  • objeto.addClass()
  • objeto.removeClass()
  • objeto.toggleClass(<<clase>>, [true,false]): añade o quita una clase, según esté o no. Los valores true y false no son obligatorios.
  • objeto.css(“propiedad_css”, “valor”): el formato de la propiedad es el original css. Pueden añadirse varias propiedades mediante un objeto:
    • {'propiedad':'valor','propiedad':'valor'}
  • objeto.width()
  • objeto.height()
  • objeto.innerWidth(): incluye padding
  • objeto.innerHeight()
  • objeto.outerWidth(): incluye borde, si se incluye como argumento true también incluye el margen
  • objeto.outerHeight()

6.6. AJAX

  • Es el acrónimo de "Asynchronous Javascript And Xml". Permite hacer solicitudes a un servidor sin necesidad de recargar la página
  • Las solicitudes y las respuestas pueden hacerse en varios lenguajes, siendo el más popular el JSON.
  • La idea es enviar una solicitud a una URL que devuelve un archivo JSON con la respuesta.
  • Los navegadores no permiten ejecutar Javascript en otros dominios ("cross-site scripting") por lo que el método nativo para hacer consultas debe usarse con archivos que se encuentren en el servidor. Para acceder a archivos de otro servidor (como en las API), se suele definir una función que maneja la respuesta (cuyo nombre lo indica el proveedor de la API) y después indicar esa función ("callback") al hacer la solicitud. El servidor hace una llamada a dicha función.
  • Las peticiones NO se pueden hacer a un archivo local, deben ser a un servidor (puede ser el servidor propio)

6.6.1. JSON

  • La sintaxis se similar a la de los objetos de Javascript. Contiene pares de "clave-valor":
    {"clave":"valor"}
    {"clave1":"valor", "clave2":"valor2"}
  • La clave solo puede ser una cadena de texto recogida entre comillas dobles.
  • Los valores pueden ser cadenas de texto, números, valores booleanos o "null":
    {"id":1234}
    {"hombre":true}
    {"clave":null}
  • Los valores también pueden ser arrays u otros objetos de JSON:
    {"clave":[{"prop1":1, "prop2":2},{"prop1":4, "prop2":2}]}
    
  • Para poder trabajar con estos archivos, hay que convertirlos en objetos del lenguaje que se necesite (PHP/Javascript):
    • JSON.stringify(<<objeto>>); (Javascript: convierte un objeto en una cadena de texto JSON)
    • JSON.parse(<<json>>); (Javascript: convierte una cadena de texto en formato JSON en un objeto Javascript)
    • json_encode(<<objeto>>); (PHP: convierte un objeto PHP en un texto JSON)
    • json_decode(<<texto>>); (PHP: transforma texto JSON en un objeto PHP);

6.6.2. Solicitudes con JQuery

  • $.getJSON(<<direccion>>, function(data){<<operaciones con la respuesta>>}).fail(function(e){<<operaciones si hay error>>});
  • $.ajax({url: <<direccion>>, datatype: "jsonp", success: function(data){<<operaciones con la respuesta>>}});

6.6.3. Solicitudes con AngularJS

  • Consultar apartado 6.7.4.

6.6.4. Solicitudes con Javascript nativo

  • XMLHttpRequest()
    var xhttp = new XMLHttpRequest();
    xhttp.open(<<tipo de petición: GET o POST>>, <<direccion>>, <<asíncrono: true o false>>);
    xhttp.send();
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            document.getElementById("demo").innerHTML = this.responseText;
        }
    };
  • Para IE 5/6: xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  • fetch(url, [{init}]) (hay que comprobar compatibilidad con navegadores)
    fetch(url, [init])
    .then(response => return response.json())
    .then(data => console.log(data.name))
    .catch(err=>console.error(err));
    • response.json() extrae el json de la respuesta HTTP de fetch()
      var pages = [];
      fetch("item.html").then(function(response){
      response.text().then(function(text){
          pages.push(text);
      });
      var miInit = { method: 'GET',
      headers: misCabeceras,
      mode: 'cors',
      cache: 'default'
      };
    • fetch también permite subir archivos

6.6.5. Recepción en el servidor (PHP)

  • Con la función json_encode() podemos transformar objetos de PHP en JSON para que el cliente pueda recibir las respuestas:
    <?php
        $myObj->name = "John";
        $myObj->age = 30;
        $myObj->city = "New York";
        $myJSON = json_encode($myObj);
        echo $myJSON;
    ?>
  • También funciona con arrays.
  • Con json_decode($_GET["variable"]) se recibe la petición (transforma de JSON a objeto PHP) y se imprime (con "echo") la respuesta:
    $obj = json_decode($_GET["x"], false);
    $conn = new mysqli("myServer", "myUser", "myPassword", "Northwind");
    $result = $conn->query("SELECT name FROM ".$obj->table." LIMIT ".$obj->limit);
    $outp = array();
    $outp = $result->fetch_all(MYSQLI_ASSOC);
    echo json_encode($outp);

6.7. AngularJS

  • Es una librería de Javascript, como JQuery. Extiende los atributos de los elementos HTML con "directivas" y vincula datos con HTML a través de "expresiones".
  • También se puede usar como “framework” (marco de trabajo) con el sistema MVC (Model-View-Controller).
  • Se añade a la página de forma similar a JQuery:
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>

6.7.1. Directivas

  • ng-app: se coloca en el elemento que contendrá la "aplicación" de AngularJS.
    <div ng-app>
    <div ng-app="ejemplo">
  • ng-controller: indica el controlador de la aplicación si se ha definido uno.
    <div ng-app="myApp" ng-controller="personCtrl">
  • ng-model: vincula un elemento de entrada de texto (<input><select>, ...) a los datos de la aplicación.
    <input type="text" ng-model="nombre"/>
  • ng-bind: vincula un dato de la aplicación a un elemento HTML.
    <p ng-bind="nombre"></p>
  • ng-init: incializa variables de la aplicación.
    <div ng-app ng-init="nombre='ricardo'">
  • ng-repeat: repite un elemento HTML:
    <li ng-repeat="x in names">{{ x }}</li>
  • Directivas anteriores precedidas de "data-"

6.7.2. Expresiones

  • Van englobadas dentro de llaves dobles: {{ nombre }}
  • Hacen lo mismo que la directiva ng-bind.
  • Pueden contener variables u otro tipo de expresiones
    <p>{{ 5 + 6 }}</p>

6.7.3. Módulos

  • Los módulos definen las aplicaciones y se escriben dentro de una etiqueta <script>
    var app = angular.module('MiApp', []);
  • Cuando se inicia la aplicación con la directiva ng-app, hay que indicar su nombre: ng-app="MiApp"
  • Los controladores "controlan" los datos de la aplicación.
    app.controller('MiCntrl', function($scope){
        $scope.nombre = "ricardo";
        $scope.apellido = "sanz";
        $scope.fullName = function() {
            return $scope.nombre + " " + $scope.apellido;
        };
    });
    • $scope es el objeto de la aplicación, funciona de manera similar a this.
    • Esta manera de iniciar variables es preferida a usar la directiva ng-init.
    • Los controladores se indican con la directiva ng-controller.

6.7.4. Otras utilidades

  • $http: permite hacer peticiones al servidor y obtener respuestas
    $http({
            method : "GET",
            url : "welcome.php"
        }).then(function todoCorrecto(response) {
            $scope.myWelcome = response.data.nombre;
        }, function hayErrores(response) {
            $scope.myWelcome = response.statusText;
        });
    $http.get("welcome.php")
        .then(function(response) {
            $scope.myWelcome = response.data.nombre;
        });
    • Propiedades de la respuesta response:
      • data
      • headers
      • status
      • statusText

6.8. React

6.8.1. Introducción

  • Es una librería de Javascript para crear interfaces de usuario. Puede usarse con una etiqueta script como JQuery o a través de Node.js

6.8.2. Instalación con Node

  • Requiere de Node >= 6 y npm >= 5.2
  • En la carpeta raíz del proyecto:
    npx create-react-app . 
  • npm start #inicia en modo desarrollo

6.8.3. Pasar a producción (Node)

  • npm run build