• 23. April 2016

Undo und Redo mit redux, @ngrx/store und Angular 2

Das Muster hinter Redux, welches @ngrx/store für Angular 2 implementiert, erleichtert einige Aufgaben bei der Verwaltung komplexer UIs. Unter anderem vereinfacht es Undo/Redo-Szenarien drastisch. Dieser Beitrag geht darauf anhand meines Beispiels zum Verwalten von Flugbuchungen ein.

Zum Bereitstellen der gewünschten Funktionalität erhält der Zustand zwei Stacks: Der undoStack beinhaltet alle vorherigen Zustände, zu denen der Entwickler via Undo zurückkehren kann. Der Stack redoStack erhält hingegen alle rückgängig gemachten Zustände, die die Anwendung bei einem Redo wieder herstellen kann:

export var initialBoardingState: BoardingState = {
    undoStack: [],
    redoStack: [],
    buchungen: [],
    message: "",
    statistik: {
        countBoarded: 0,
        countBooked: 0,
        countCheckedIn: 0
    }
};

Beide Stacks repräsentiert das Beispiel zur Vereinfachung als Array. Die einzelnen Aktionen fügen den bisherigen Zustand am Ende des Undo-Stacks ein. Da ein Redo nur unmittelbar nach einem Undo und nicht nach einer herkömmlichen Aktion möglich ist, erhält redoStack ein leeres Array:

function buchungStateChanged(state: BoardingState, buchung): BoardingState {

    [...]

    return {
        undoStack: [...state.undoStack, state],
        redoStack: [],
        buchungen: [...],
        statistik: [...],
        message: ""
    };
}

Um einen neuen Eintrag zu einem immutable Array hinzuzufügen, nutzt dieses Beispiel den mit EcmaScript 6 eingeführten Spread-Operator (drei Punkte als Prefix): Die Angabe ...state.undoStack repräsentiert die Einträge dieses Arrays in der Form eintrag1, eintrag2, ..., eintragN. Die Schreibweise [...state.undoStack, state] ergänze diese Sequenz um das Element state und erzeugt mit dieser ein neues Array.

Die Aktion, welche sich um das Undo kümmert, findet sich nachfolgend. Sie entfernt das letzte Element aus dem Undo-Stack. Dabei handelt es sich um jenen Zustand, den es wiederherzustellen gilt. Damit der Anwender zum aktuellen Zustand per Redo zurückkehren kann, fügt sie diesen zum neuen Redo-Stack hinzu. Abgesehen davon übernimmt der neue Zustand die Daten aus dem wiederherzustellenden.

function undo(state: BoardingState) {
    var oldState = state;
    var prevState = state.undoStack[state.undoStack.length-1];

    // Neues Array ohne dem letzten Element mit slice erzeugen
    var newUndoStack = state.undoStack.slice(0, state.undoStack.length-1);

    return {
        undoStack: newUndoStack,
        redoStack: [...oldState.redoStack, oldState],
        buchungen: prevState.buchungen,
        message: prevState.message,
        statistik: prevState.statistik,
    }
}

Die Redo-Aktion funktioniert ähnlich: Sie entfernt das letzte Element aus dem Redo-Stack und nutzt dessen Eigenschaften für den neuen Zustand. Das gilt sogar für den undoStack dieses Elements:

function redo(state: BoardingState) {
    var oldState = state;
    var redoState = state.redoStack[state.redoStack.length-1];
    var newRedoStack = oldState.redoStack.slice(0, oldState.redoStack.length-1);

    return {
        undoStack: redoState.undoStack,
        redoStack: newRedoStack,
        message: redoState.message,
        buchungen: redoState.buchungen,
        statistik: redoState.statistik
    }    
}

 

 
Hier können Sie eine Anfrage für eine unverbindliche Schulung ode Beratung bzw. einen Workshop erstellen.
 
Unverbindliche Anfrage
 
 

Schulungen

Angular Schulung: Strukturierte Einführung

Lernen Sie in dieser interaktiven Schulung anhand einer Beispielanwendung den Einsatz von Angular für Ihre erfolgreichen Projekte kennen. Sie durchdringen die Hintergründe und bauen von der ersten Minute an auf Best Practices auf.

Details

Advanced Angular: Enterprise-Anwendungen und Architektur

In dieser Schulung erfahren Sie alles für die Entwicklung großer Anwendungen mit Angular: Mono-Repos, Micro-Apps, State Management, Performance und mehr

Details

Angular: Strukturierte Einführung

Seit der Ankündigung von Angular (2+) fragen sich Entwicklungs-Teams, welche Migrationspfade für AngularJS-1.x-Anwendungen vorliegen werden. Das im Lieferumfang von Angular enthaltene ngUpgrade bietet eine Antwort darauf. Es erlaubt einen Parallelbetrieb von AngularJS 1.x und Angular (2+) und stellt somit die Grundlage für eine schrittweise Migration dar.

Details

Progressive Web-Apps mit Angular

Progressive Web Apps bieten den Komfort nativer Anwendungen, indem sie auf moderne Browser APIs, wie Service Worker, setzen. Sie sind installierbar sowie offlinefähig und nutzen Hintergrundprozesse für Datensynchronisation und Push-Notifications. Diese Schulung zeigt anhand eines durchgehenden Beispiels was sich genau hinter diesem neuen Konzept verbirgt, wie solche Anwendungen mit Angular entwickelt werden und wie Sie in Ihren Projekten von den dahinterstehenden Ideen profitieren.

Details

Reaktive Architekturen mit Angular und Redux

Dieses interaktive Seminar vermittelt, wie Sie reaktive Anwendungen mit Angular entwickeln können.

Details

TypeScript

TypeScript gibt Ihnen alle Möglichkeiten der neuen JavaScript-Standards und zusätzlich ein statisches Typsystem, das dabei hilft, Fehler möglichst früh zu erkennen. Außerdem ist TypeScript die Grundlage für Angular. In diesem interaktiven Seminar lernen Sie diese mächtige Sprache anhand einer Fallstudie kennen.

Details

Weitere Schulungen ...