0. Indicar el acceso a una página Thymeleaf
Para ello tenemos que crear un controlador que contenga las anotaciones siguientes:
@Controller:
Anotación de clase que indica que es un controlador
@RequestMapping("/")
Anotación de clase o método que indica donde localizar un servicio web
Además debemos actualizar el modelo para que Thymeleaf pueda acceder a estas variables que guarda el modelo.
package com.ximodante;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.ui.Model;
@Controller
public class ViewController {
private String appMode;
@Autowired
public ViewController(Environment env){
appMode=env.getProperty("app-mode");
}
@RequestMapping("/")
public String index(Model model){
model.addAttribute("datetime", new Date());
model.addAttribute("username", "Informatica Dantesca");
model.addAttribute("mode", "production");
return "index";
}
}
1. Crear una página Thymeleaf
Por otra parte, para mostrar una plantilla de Thymeleaf, tenemos que hacer estos pasos:
1. Colocar las librerías javascript o css que vayamos a utilizar en la carpeta scr/main/resources/static. Si queremos ser mas organizados se podran crear diferentes carpetas dentro de static (por ejemplo una para los "css", otra para los "js", etc). En nuestro caso vamos a descargar, desde sus respectivas webs:
2. Crear una plantilla Thymeleaf en la carpeta scr/main/resources/static/templates. En nuestro caso le vamos a llamar index.html .
Vamos a ver pequeños detalles
2. Separación de comportamiento entre producción y desarrollo
En Thymeleaf haremos uso de las clausulas condicionales "if". En el modelo podemos incluir una variable llamada "mode" que tome valores "development" o "production". Si es en desarrollo, vamos a utilizar las librería "bootstrap.min.css", mientras en producción vamos a utilizar "bootstrap.css". Para ello incluimos el siguiente código: <link th:if="${mode == 'development'}" rel="stylesheet" href="../static/bootstrap.css" th:href="@{/bootstrap.css}" />
<link th:if="${mode == 'production'}" rel="stylesheet" href="../static/bootstrap.min.css" th:href="@{/bootstrap.min.css}" />
Thymeleaf también permite formatear variables. En este caso la fecha (que en el modelo la hemos guardado con el nombre "datetime"
<p th:text="${#dates.format(datetime,'dd MMM yyyy HH:mm:ss')}" class="text-muted">Page was rendered today.</p>
3. Inclusión de código Angular 1.xx en la plantilla
No es mi misión explicar como va Angular. Pero veamos algunos detalles:Indicación de la aplicación y módulo de código realizados en Angular, en nuestro caso lo hemos indicado en el <body>. Observar que el controlador tiene el alias "vm".
<body ng-app="app" ng-controller="BookingsController as vm">
Para ver el contenido de las variables en angular hemos utilizado {{vm.variable}} o similar.
Tambien utilizamos la archirepetida cláusula ng-repat
El contenido de la plantilla Thymeleaf va a ser el siguiente:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>Hotel Booking App</title>
<link th:if="${mode == 'development'}" rel="stylesheet" href="../static/bootstrap.css" th:href="@{/bootstrap.css}" />
<link th:if="${mode == 'production'}" rel="stylesheet" href="../static/bootstrap.min.css" th:href="@{/bootstrap.min.css}" />
<script type="text/javascript" src="/static/angular.min.js" th:src="@{angular.min.js}"></script>
<script type="text/javascript" src="/static/app/module.js" th:src="@{/app/app.module.js}"></script>
<script type="text/javascript" src="/static/app/bookings.controller.js" th:src="@{/app/bookings.controller.js}"></script>
</head>
<body ng-app="app" ng-controller="BookingsController as vm">
<header>
<nav class="navbar navbar-default">
<div class="container-fluid">
<a class="navbar-brand" href="#"> Booking Demo JAJAJAJA</a>
</div>
<p class="navbar-text navbar-right" th:text="'Signed as ' + ${username}" style="margin-right: 10px:">Signed as Anonymous</p>
</nav>
</header>
Hello Bootstrap! How are you Folk? And you, Thymeleaf?
<div>{{vm.prova}}</div>
<div>
<div class="row">
<div class="col-lg-offset-2 col-lg-8">
<!-- Get all booking or only affordable ones -->
<div class = "btn-group" role="group">
<button ng-click = "vm.getAll()" type="button" class = "btn btn-default">All</button>
<button ng-click = "vm.getAffordable()" type="button" class = "btn btn-default">Less than {{vm.min}}</button>
</div>
<!-- Display bookings in a table -->
<table class="table">
<thead>
<tr>
<th>Hotel</th>
<th>Nights</th>
<th>Price</th>
<th>Total</th>
<th style="width: 90px"></th>
</tr>
</thead>
<tr ng-repeat="booking in vm.bookings">
<td>{{booking.hotelName}}</td>
<td>{{booking.nbOfNights}}</td>
<td>{{booking.pricePerNight}}</td>
<td>{{booking.totalPrice}}</td>
<td>
<button class="btn btn-danger" ng-click="vm.deleteBooking(booking.id)">Delete</button>
</td>
</tr>
</table>
</div>
</div>
</div>
<footer class="footer" style="position:absolute; bottom:0;background-color: #f5f5f5;">
<div class="container">
<p th:text="${#dates.format(datetime,'dd MMM yyyy HH:mm:ss')}" class="text-muted">Page was rendered today.</p>
</div>
</footer>
</body>
</html>
4. Creación del código js de ángular
Para ello vamos a utilizar la carpeta scr/main/resources/static/templates para guardar 2 ficheros angular:- app.module.js (aplicación)
- bookings.controller.js (controlador)
Normalmente en angular se tiene una aplicación y varios módulos que dependen de ella. En este caso solo tenemos una aplicación.
Veamos su código
(function(){
'use strict';
angular.module('app',[]);
})();
Poco puedo decir yo aquí. Veamos el otro código. Aquí hay que remarcar como hacemos peticiones GET y POST con ángular a nuestros servicios REST, que hemos definido
Veamos como hacemos una petición GET que nos devuleve una promesa:
function getAll(){
var url = "/bookings/all";
var bookingsPromise = $http.get(url);
bookingsPromise.then(function(response) {
vm.bookings = response.data;
});
}
Veamos como realiza una petición POST
function deleteBooking(id){
var url = "/bookings/delete/" + id;
$http.post(url).then(function(response){
vm.bookings = response.data;
});
}
Tambien hay que publicar las funciones creadas:
vm.bookings = []; vm.getAll = getAll; vm.getAffordable = getAffordable; vm.deleteBooking = deleteBooking; vm.prova="Mi prueba"; vm.min=23;
Y el contenido final del fichero js booking.controller.js es:
(function () {
'use strict';
angular
.module('app')
.controller('BookingsController',BookingsController);
BookingsController.$inject = ['$http'];
function BookingsController($http) {
var vm = this;
vm.bookings = [];
vm.getAll = getAll;
vm.getAffordable = getAffordable;
vm.deleteBooking = deleteBooking;
vm.prova="Mi prueba";
vm.min=23;
init();
function init(){
getAll();
}
function getAll(){
var url = "/bookings/all";
var bookingsPromise = $http.get(url);
bookingsPromise.then(function(response) {
vm.bookings = response.data;
});
}
function getAffordable(){
var url = "/bookings/affordable/" + vm.min;
var bookingsPromise = $http.get(url);
bookingsPromise.then(function(response) {
vm.bookings = response.data;
});
}
function deleteBooking(id){
var url = "/bookings/delete/" + id;
$http.post(url).then(function(response){
vm.bookings = response.data;
});
}
}
})();












