Andrej Sládkovič, AngularJS a Node.js

Zápisník experimentátora

Hierarchy: Node.js

 dnešním článku budeme pokračovat ve zpracování básně Marína od Andreje Sládkoviča. Cílem je dostat tuto báseň do Arduina, ale protože pomocí samotného Arduina by vývoj trval dlouho, uděláme malou zastávku v Node.js. Vytvoříme si HTTP server v Node.js, který bude zajišťovat backend pro AngularJS aplikaci. Tuto aplikaci později využijeme v Arduinu, kdy server v Node.js nahradíme serverem v Arduinu.

Báseň od Andreje Sládkoviča má 291 slok. V jednu chvíli budeme zobrazovat pouze jednu sloku na obrazovce. Proto použijeme čtyři ovládací tlačítka, pomocí kterých můžeme listovat v celé básni. Jak báseň vypadá v prohlížeči vidíte na obrázku.

HTTP

Aplikace je navržena jako jednostránková aplikace v AngularJS. Používá následující rozhraní.

  • / - Ze serveru se stáhne HTML stránka, na které jsou odkazy na další stránky. Stáhne se postupně Bootstrap, AngularJS a potom samotná aplikace v JavaScriptu. Vše se stahuje z Internetu, abychom nemuseli do Arduina dávat velké soubory.
  • /sladkovic.js - Zdrojový kód AngularJS aplikace.
  • /marina?verse=X - Stažení textu konkrétní sloky.
  • /marinaverses - Získání počtu slok v básni.

HTML

Zdrojový kód HTML stránky vypadá takto. AngularJS aplikace je uzavřena ve značce <div ng-app="sladkovicApp" ng-controller="sladkovicCtrl">. V kódu snadno rozeznáte, jak se vytvářejí tlačítka a připojují se na funkce. Například skok na první sloku básně uděláte pomocí <button ng-click="doFirst()">Prvý</button>. Výpis samotné básně je dělán pomocí speciálních značek pro AngularJS. Například číslo aktuální sloky zobrazíte pomocí {{verse}}.

<!DOCTYPE html>
<html lang="sk">
<head>
  <title>Andrej Sládkovič - Marína</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
  <script src="sladkovic.js"></script>
</head>

<body>
  <div ng-app="sladkovicApp" ng-controller="sladkovicCtrl">
  <div class="container">
  <div class="row">
    <div class="col-sm-12">
      <h1>Andrej Sládkovič - Marína</h1>
      <p><button ng-click="doFirst()">Prvý</button> <button ng-click="doPrev()">Predchádzajúci</button> <button ng-click="doNext()">Nasledujúci</button> <button ng-click="doLast()">Posledný</button></p>
    </div>
  </div>

  <div class="row">
    <div class="col-sm-12">
      <p>Verš {{verse}}/{{maxverse}}</p>
      <pre>{{text}}</pre>
    </div>
  </div>

  </div>
  </div>
</body>

</html>

AngularJS

Zdrojový kód v JavaScriptu je snadno čitelný. Komunikace mezi HTML a javasciptom se děje pomocí proměnné $scope. Pomocí funkce $http.get si ze serveru stáhneme všechny potřebné informace. Pěkný příklad na funkci, která je využívána k získání textu konkrétní sloky, najdete ve funkci updateText. Je volána z mnoha jiných funkcí, které jsou napojeny na tlačítka na stránce.

var app = angular.module('sladkovicApp', []);

app.controller('sladkovicCtrl', ['$scope', '$http', function($scope, $http) {

  $scope.verse = 1;
  $scope.maxverse = 1;
  $scope.text = '';

  $http.get('/marinaverses')
    .then(function(response) {
      console.log(response);
      $scope.maxverse = response.data.maxverse;
    }, function(error) {
      console.log(error);
    });

  updateText();

  function updateText() {
    $http.get('/marina?verse=' + $scope.verse)
      .then(function(response) {
        console.log(response);
        $scope.text = response.data;
      }, function(error) {
        console.log(error);
      });
  }

  $scope.doFirst = function() {
    if($scope.verse>1) {
      $scope.verse = 1;
      updateText();
    }
  }

  $scope.doPrev = function() {
    if($scope.verse>1) {
      $scope.verse--;
      updateText();
    }
  }

  $scope.doNext = function() {
    if($scope.verse<$scope.maxverse) {
      $scope.verse++;
      updateText();
    }
  }

  $scope.doLast = function() {
    if($scope.verse<$scope.maxverse) {
      $scope.verse = $scope.maxverse;
      updateText();
    }
  }

}]);

Node.js

Poslední částí aplikace je samotný HTTP server. je vygenerován pomocí aplikace express-generator. Z vygenerovaného kódu jsem odstranil vše nepotřebné a nechal pouze tu část, která dodává statický obsah. Ta slouží k odeslání úvodní HTML stránky a javascriptu s AngularJS aplikací do prohlížeče. Doplnil jsem do kódu pouze pole s jednotlivými slokami (var marina) a dvě funkce, které odesílají odpovědi do AngularJS aplikace (app.get('/marina'... a app.get('/marinaverses'...).

Aplikaci pro Node.js si nainstalujete pomocí příkazu npm install a spustíte ji pomocí příkazu npm start.

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var app = express();

var marina = [
  "Ja sladké túžby, túžby po kráse\nspievam peknotou nadšený,\na v tomto duše mojej ohlase\nsvet môj je celý zavrený;\nz výsosti Tatier ona mi svieti,\nona mi z ohňov nebeských letí,\nona mi svety pohýna;\nona mi kýva zo sto životov:\nNo centrom, živlom, nebom, jednotou\nkrás mojich moja Marína!",
...
  "Marína moja! teda tak sme my\nako tie božie plamene,\nako tie kvety v chladnej zemi,\nako tie drahé kamene;\npadajú hviezdy, aj my padneme,\nvädnú tie kvety, aj my zvädneme,\na klenoty hruda kryje:\nAle tie hviezdy predsa svietili,\na pekný život tie kvety žili,\na diamant v hrude nezhnije!",
];

// uncomment after placing your favicon in /public
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public'), {'extensions': ['html']}));

app.get('/marina', function (req, res) {
  var id = req.query.verse || 1;
  res.send(marina[id-1]);
});

app.get('/marinaverses', function (req, res) {
  res.json({maxverse: marina.length});
});

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

Zdrojový kód

Zdrojový kód se nachází na serveru GitHub.

Pokud máte nainstalovaný program git, můžete si zdrojové kódy nainstalovat například takto. Pokud ho nemáte, dají se stáhnout i jako zip archiv. Spusťte si konzolu příkazového řádku. Důležitý je poslední řádek, který nainstaluje všechny související knihovny, které jsou v souboru package.json.

cd d:
mkdir arduino
cd arduino
git clone https://github.com/roboulbricht/arduinoslovakia
cd arduinoslovakia\node.js\sladkovic_demo
npm install

20.01.2018


Menu