AJAX mit Ruby on Rails und :remote => true

Mit :remote => true bietet das das Ruby Webframework Rails eine sehr einfache Methode um mit Hilfe von AJAX eine Webseite zu aktualisieren. Dieses kann z.B. einfach zu HTML-Elementen wie Formulare, Buttons, Links und Checkboxen hinzugefügt werden. Dadurch werden z.B. gefüllte Formulare nicht mehr wie gewohnt an den Webserver gesendet, sondern mit AJAX. Man erspart dem Benutzer dadurch einen lästigen ggf. langwierigen Seitenaufbau. Im Gegenzug muss man sich aber selber um eine Aktualisierung der Webseite mit Hilfe von jQuery oder JavaScript kümmern.

Folgender Code in einem View erstellt eine Checkbox welche bei einem Klick mit Hilfe von AJAX einen HTTP Post an die angeben URL sendet:

check_box_tag( 
  "my_checkbox", "i_am_checked", false, 
  data: { 
    remote: true, 
    url: "my_checkbox/click", 
    method: "POST" 
  }
)

Der Request muss in diesem Fall vom my_checkbox Controller angenommen und verarbeitet werden. Um die Ansicht des Benutzers zu ändern schickt man mit den bekannten Rails Methoden Javascript an den Browser zurück. Im my_checkbox_controller.rb erweitert man z.B. die respond_to einfach um ein format.js:

def click
  respond_to do |format|
    format.js {}
  end
end

Der dazugehörigen View (click.js.erb) wird somit an den Browser zurück gesendet und man kann per JavaScript die Webseite aktualisieren:

console.log('I am the response!')
alert('You clicked the checkbox!')

Rails bietet mit :remote=>true somit eine wirklich einfach Methode um AJAX für seine Webseite einzusetzen!

Achim Ledermüller
Achim Ledermüller
Lead Senior Systems Engineer

Der Exil Regensburger kam 2012 zu NETWAYS, nachdem er dort sein Wirtschaftsinformatik Studium beendet hatte. In der Managed Services Abteilung ist unter anderem für die Automatisierung des RZ-Betriebs und der Evaluierung und Einführung neuer Technologien zuständig.

Einfache asynchrone Aufrufe in JavaScript mit Async.js

JavaScript ist eine Programmiersprache die als Non-Blocking bezeichnet wird: Wenn ein Funktionsaufruf längere Zeit in Anspruch nimmt, wie das z.B. bei AJAX oder Timeouts der Fall ist, wird der Thread des Codes nicht schlafen gelegt bis der Funktionsaufruf beendet ist, sondern läuft sofort weiter. Es ist nicht möglich auf die Auswirkungen des Aufrufs zu warten, außer man benutzt eine weitere Funktion die dann als Callback aufgerufen wird.
In den Anfangstagen von JavaScript hatte dieses Vorgehen durchaus seinen Sinn: Da die Sprache nur für einfache Animationen gedacht war und kein Multithreading unterstützt hat (was sie übrigens auch heute nur mithilfe von WebWorkern beherrscht), wären sonst bei jedem Timeout die Animationen der Website stehen geblieben. Heute wird JavaScript sehr oft verwendet um per AJAX Inhalte nachzuladen. Komplexere Funktionalität erfordern dann aber immer öfter mehrfach ineinander verschachtelte Callbacks, was den Code schnell schwer durschaubar werden lässt.
Als Beispiel verwende ich nur setTimeout(), man kann sich an dieser Stelle aber auch beispielsweise einen HTTP-GET per AJAX oder eine beliebige andere asynchrone Funktion vorstellen. Je mehr Funktionen dazu kommen, desto verwirrender wird der Code:

setTimeout(function(){
   alert("Du bist jetzt seit einer Sekunde auf dieser Seite");
   setTimeout(function(){
       alert("Seit der letzten Meldung sind 10 Sekunden vergangen");
       setTimeout(function(){
           alert("Eingeschlafen?");
       }, 3600*1000);
   }, 10000);
}, 1000)

Natürlich könnte man stattdessen auch einfach eine Funktion schreiben, die eine Liste an Funktionen als Argumente annimmt, und diese dann alle in Serie aufruft. Einfacher geht es allerdings mit Async.js:

async.series([
    function(callback) {
        setTimeout(function() {
           alert("Du bist seit einer Sekunde auf dieser Seite");
           callback();
        }, 1000);
    },
    function(callback) {
        setTimeout(function() {
            alert("Seit der letzten Meldung sind 10 Sekunden vergangen.");
            callback();
        }, 10000);
    },
    function(callback) {
        setTimeout(function(callback) {
            alert("Eingeschlafen?");
            callback();
        }, 1000*3600)
    }
]);

Die Funktion series führt alle Funktionen der Reihe nach aus. Mithilfe des Callbacks wird Async.js mitgeteilt wenn die Funktion beendet ist. Dieser Code ist zwar länger, aber dafür wesentlich lesbarer: Es ist auf einen Blick zu erkennen, wie lange die einzelnen Schritte dauern und welcher Code dann ausgeführt wird. Auch bei sehr vielen voneinander abhängigen Aufrufen bleibt die Zahl der Einrückungen übersichtlich.
Dieses Beispiel zeigt nur den einfachsten Anwendungsfall von Async.js. Es gibt neben series noch viele andere Strategien um Aufrufe zu synchronisieren. Mit parallel werden die Funktionen nicht seriell, sondern parallel gestartet. Ein Callback wird aufgerufen sobald alle Funktionen fertig abgearbeitet wurden. Außerdem gibt es noch viele funktionale Strategien wie map, reduce und filter, die benutzt werden können um eine Collection aus Daten einfach mit asynchronen Funktionen zu verändern.

Kleber für middleware

Viele Webanwendungen werden heute fast ausschließlich in Javascript geschrieben. Frameworks existieren wie Sand am Meer und bieten mannigfaltige Möglichkeiten. Bei den richtig großen muss man gar kein HTML mehr anfassen, sie nehmen einem alles an Arbeit ab – und das ist gut so. Was aber passiert denn mit der Middleware? Also der Teil der Applikation wo die Datenbank befragt wird und Sessions gesteuert werden?
Normalerweise verwendet man hier eine andere Sprache, z.B. PHP, Python oder Perl. Doch hier sind Probleme und Schwierigkeiten bereits vorprogrammiert. Die verwendeten Frameworks sind oft zu groß und die meiste Zeit geht dafür verloren, Datenstrukturen von Links nach Rechts zu konvertieren. Vom Kontextwechsel ganz zu schweigen: Variablen mit oder ohne Dollarzeichen, Strichpunkte Ja/Nein, unterschiedliche Objektorientierung usw – gräuslich …
Seit einiger Zeit begibt sich Javascript auf der Konsole wie Nodejs/V8 oder Rhino in die stabilen Zweige der Distributionen und es schießen immer mehr Frameworks aus dem Boden welche die großen Klassiker im Webumfeld ersetzen können (nicht müssen ^^). Warum also nicht mal eine Sprache für alle Teile der Applikation zu verwenden?
Einer dieser Leichtfüßer für Nodejs ist Connect von Senchalabs welches unter der MIT Lizenz veröffentlicht wurde. Ein kleiner Exkurs:

var connect = require('connect');
var http = require('http');
var app = connect();
app.use(connect.logger());
app.use(connect.cookieParser());
app.use("/data", function(req, res) {
    res.setHeader("Content-Type", "application/json");
    res.end(JSON.stringify({
        success: true,
        count: 2,
        data: [{
            firstname: "Eduart",
            surname: "Zimmermann"
        }, {
            firstname: "Heidrun",
            surname: "Bumbel"
        }]
    }));
});
http.createServer(app).listen(3000);

Das Plugin Prinzip von Connect ist sehr interessant und vereinfacht das Handling von gleichartigen Anfragen. Die Plugins (Middleware) sind in Reihe geschaltet und können so bereits viel Vorarbeit leisten bis die eigentlich konkrete Implementierung. So können z.B. JSON Requests, Cookies oder Authentifizierung bereits vorher abgearbeitet werden und stehen dann schon bereit.
Das alles setzt natürlich ein einigermaßen aktuelles System (was der Entwickler grundsätzlich besitzt) voraus auf dem Nodejs und sein Paket Manager npm als Distro Pakete verfügbar sind (z.B. Ubuntu). Aber selbst kompilieren von Hand ist ohne großen Aufwand möglich. Am besten gleich probieren und freuen …

Marius Hein
Marius Hein
Head of Development

Marius Hein ist schon seit 2003 bei NETWAYS. Er hat hier seine Ausbildung zum Fachinformatiker absolviert, dann als Application Developer gearbeitet und ist nun Leiter der Softwareentwicklung. Ausserdem ist er Mitglied im Icinga Team und verantwortet dort das Icinga Web.

JIT – Javascript more Interactive Than ever

We are pretty excited to hear that JIT (JavaScript InfoVis Toolkit) developed by Nicolas Garcia Belmonte, has got a heap of new features coming in version 2.0. The coolest Javascript library we’ve come across, JIT makes viewing dry data like your server landscape, as mesmerizing as a rubric cube – you just can’t stop playing with it.
Ranging from radial layouts of tree directories, space trees and pie graphs in pie graphs, JIT has some ingenious ways of showing relationships between things. For example the Rgraphs allow users to click on nodes to zoom into, while adjusting the overall graph to still show its relationships to other nodes. Thanks to precisely this visualisation, which Icinga web developers have used for status maps – we can click between hosts and see the dependencies that exist.

We like JIT because it’s so easily extensible, all visualization classes can be added to or written over, and combined to create completely new views. It also displays well on all the popular browsers like Firefox, IE, Safari etc, and works well with any DOM manipulation framework – whilst being of course open source under BSD.
[youtube]//www.youtube.com/watch?v=CpXpAiZT1n0[/youtube]
Believe it or not as Nicolas promises in his JIT blog, graphs can get more dynamic than that – check out his sneak-peak videos of new zooming and panning functions, animated and interactive tree maps which allow nodes to be deleted and shifted around. Crazy looking stuff and we’re looking forward to it!

YAHOO! fürs JavaScript


Bereits in einem vergangenem Blogeintrag wurde das bekannteste JavaScript Framework überhaupt vorgestellt: Prototype. Leider ist es relativ groß und ohne Plugins nur für ‘niedere’ Arbeiten gedacht (Klassen erstellen, erweitern, Ajax, JSON).
Als Alternative kommt hier YUI ins Spiel. YUI ist ein von YAHOO! entwickeltes JavaScript Framework welches stärker auf Benutzerinteraktion abgestimmt ist. So bietet es von Grund auf Objekte um Autovervollständigung oder Kalender ohne viel Aufwand auf die Seite zu zaubern.
All diese Steuerelemente unterliegen einem modularem Aufbau welcher eine Generalisierung von Ereignissen und den Zugriff auf DOM Objekte erlaubt.
Lange Rede, kurzer Sinn – Ein Autocompletefeld ist schnell erstellt

Die Webseite der YUI Bibliothek ist mit Beispielen gespickt, was einem das Arbeiten deutlich erleichert.
Alle Komponenten werden als Einzeldateien oder als Gesamtpaket zu Verfügung gestellt. Auch ein Abhängigkeitskonfigurator ist auf der Webseite vorhanden. In ihm werden alle benötigten Features eingetragen und man erhält eine URL welche alle Scriptdateien nachzieht – vorausgesetzt Internet ist verfügbar.
Am besten gefällt mir allerdings das “Container” Objekt. Mit ihm werden alle möglichen Layer realisiert. Vom einfach beweglichen Popup bis hin zum vollgestopften Dialog welcher modal angezeigt wird durch Eventhandler eigenständig Ajaxanfragen an den Server sendet.

Dieses Framework war mir bis vor kurzem völlig unbekannt – jetzt möchte ich es nicht mehr missen.
In diesem Sinne ein schönes Wochende!

Marius Hein
Marius Hein
Head of Development

Marius Hein ist schon seit 2003 bei NETWAYS. Er hat hier seine Ausbildung zum Fachinformatiker absolviert, dann als Application Developer gearbeitet und ist nun Leiter der Softwareentwicklung. Ausserdem ist er Mitglied im Icinga Team und verantwortet dort das Icinga Web.