smart | Webentwicklung
Alles rund um HTML5, PHP, WordPress & Co.

Todo-App: 3. Liste von Models via Collection

12. November 2012
Stephan
Todo-App mit backbone.js und CoffeeScript entwickeln

In diesem Teil werden wir eine sogenannte Collection erstellen. Eine solche Collection ist im Grunde nichts weiter als eine (geordnete) Liste von Models einer Klasse.

In unserem Fall benötigen wir eine Liste, die alle von uns angelegten Aufgaben (Todos) beinhaltet. Dabei ermöglicht uns die Collection z.B. alle Aufgaben (Todo-Models) vom Server bzw. in unserem Fall via LocalStorage aus dem Browser-Speicher zu laden.

In der Dokumentation zu backbone.js findet ihr einen guten Überblick über alle relevanten Methoden einer Collection.

Teile der Artikel-Serie

Zur Übersicht eine Auflistung aller erschienenen Artikel der Artikel-Serie „Tutorial: Todo-App mit backbone.js & CoffeeScript erstellen“:

  1. Vorbereitungen vornehmen (Projektverzeichnis anlegen etc.)
  2. Model erstellen
  3. Collection – Liste von Models
  4. View-Struktur & Grundlagen einer backbone.js View
  5. Restliche Views implementieren
  6. Controller implementieren & App fertigstellen
  7. Daten mit Ruby on Rails per REST-API serverseitig speichern

Vorüberlegungen zum Aufbau der Collection

Wie bereits erwähnt, soll unsere Collection alle unsere Aufgaben beinhalten. Somit muss die Collection Models der Klasse Todo verwalten. Außerdem sollen die Models, um genauer zu sein die Model-Daten, via LocalStorage-API im lokalen Speicher des Browser gespeichert und aus diesem geladen werden.

Weiterhin benötigen wir für unsere Todo-Statistik die Anzahl aller Aufgaben, die bereits erledigt bzw. noch nicht erledigt/verbleibend sind. Für diese Funktionalität werden wir zwei Methoden implementieren.

Collection-Klasse erstellen

Zum Anfang erstellen wir uns wieder ein Grundgerüst der benötigten Klasse. Dazu legen wir die Datei TodoCollection.coffee im Verzeichnis app/collections an. In diese Datei schreiben wir den folgenden Code:

class TodoApp.Collections.TodoCollection extends Backbone.Collection

JavaScript:

TodoApp.Collections.TodoCollection = Backbone.Collection.extend({
});

Unsere erstellte TodoCollection ist wie ihr sehen könnt von der Klasse Backbone.Collection abgeleitet.

Als nächstes definieren wir, dass die Collection Models der Klasse Todo verwaltet. Dazu müssen wir nur eine Zeile Code hinzufügen:

class TodoApp.Collections.TodoCollection extends Backbone.Collection
    model: TodoApp.Models.Todo

JavaScript:

TodoApp.Collections.TodoCollection = Backbone.Collection.extend({
    model: TodoApp.Models.Todo
});

Collection instanziieren und Models hinzufügen

Eine Collction kann wie jedes andere Objekt auch ganz normal instanziiert werden:

todos = new TodoCollection()

In JavaScript:

var todos = new TodoCollection();

Bei der Instanziierung können wir auch direkt unsere Models übergeben:

todo1 = new Todo(
    title: 'Aufgabe 1'
    done: true
)
todo2 = new Todo(
    title: 'Aufgabe 2'
    done: true
)

todos = new TodoCollection([
    todo1
    todo2
])

In JavaScript:

var todo1 = new Todo({
    title: 'Aufgabe 1', 
    done: true
});
var todo2 = new Todo({
    title: 'Aufgabe 2', 
    done: true
});

var todos = new TodoCollection([
    todo1,
    todo2
]);

JSON-Objekte würden prinzipiell aber auch funktionieren:

todos = new TodoCollection([
    title: 'Aufgabe 1'
    done: true
,
    title: 'Aufgabe 2'
    done: true
])

In JavaScript:

var todos = new TodoCollection([
    {
        title: 'Aufgabe 1',
        done: true
    },
    {
        title: 'Aufgabe 2',
        done: true
    }
]);

In diesem Fall würde die Collection für jedes JSON-Objekt eine neue Model-Instanz erstellen.

Analog können einer bereits vorhandenen Collection mittels create weitere Models hinzugefügt werden.

LocalStorage

Für backbone.js gibt es bereits die Erweiterung backbone-localStorage. Wir brauchen uns diesbezüglich also um nichts kümmern, sondern unsere Collection nur wie folgt anpassen:

class TodoApp.Collections.TodoCollection extends Backbone.Collection
    model: TodoApp.Models.Todo

    localStorage: new Store('TodoApp')

JavaScript:

TodoApp.Collections.TodoCollection = Backbone.Collection.extend({
    model: TodoApp.Models.Todo,

    localStorage: new Store('TodoApp')
});

Von nun an werden die Model-Daten im lokalen Speicher des Browser gespeichert und von da geladen.

Zur Info: Die Erweiterung macht nichts anderes als die sync-Funktion, die bei jedem Speichern und Laden aufgerufen wird, zu überschreiben.

Methode zum Filtern der Model

Jetzt wollen wir die zwei Methoden impementieren, die die Aufgaben anhand ihres Status filtern.

Die erste Methode nennen wir einfach done. Diese Methode soll uns alle Aufgaben liefern, deren Status erledtigt ist. Dazu ergänzen wir unsere TodoCollection:

class TodoApp.Collections.TodoCollection extends Backbone.Collection
    model: TodoApp.Models.Todo

    localStorage: new Store('TodoApp')

    done: ->
        @filter((todo) ->
            todo.get('done')
        )

JavaScript:

TodoApp.Collections.TodoCollection = Backbone.Collection.extend({
    model: TodoApp.Models.Todo,

    localStorage: new Store('TodoApp'),

    done: function()
    {
        return this.filter(function(todo)
        {
            return todo.get('done');
        });
    }
});

Zum Filtern nutzen wir die filter-Funktion, die durch underscore.js bereitgestellt wird.

Wir durchlaufen hier einfach alle Todo-Model, die sich in unserer TodoCollection befinden. Hierbei prüfen wir, ob der Status done beim jeweiligen Model true ist. Anschließend werden alle Models zurückgeliefert, bei denen das der Fall ist.

In gleicher Weise können wir nun auch eine Methode hinzufügen, die uns die unerledigten Aufgaben zurückgibt:

class TodoApp.Collections.TodoCollection extends Backbone.Collection
    model: TodoApp.Models.Todo

    localStorage: new Store('TodoApp')

    done: ->
        @filter((todo) ->
            todo.get('done')
        )

    remaining: ->
        @without.apply(@, @done())

JavaScript:

TodoApp.Collections.TodoCollection = Backbone.Collection.extend({
    model: TodoApp.Models.Todo,

    localStorage: new Store('TodoApp'),

    done: function()
    {
        return this.filter(function(todo)
        {
            return todo.get('done');
        });
    },

    remaining: function()
    {
        return this.without.apply(this, this.done());
    }
});

Auch hier nutzen wir mit without eine hilfreiche Funktion, die durch underscore.js bereitgestellt wird.

Was apply in diesem Zusammenhang bedeutet, ist auf stackoverflow.com sehr gut erklärt.

Fazit / Wie gehts weiter?

Wir haben nun unsere TodoCollection fertig umgesetzt. Im weiteren Verlauf des Tutorials wir dann genauer verstehen, wozu wir die Collection brauchen bzw. welche Vorteile eine solche Collection mit sich bringt.

Im nächsten Teil beschäftigen wir uns dann mit den Views, die wir für unsere Todo-App benötigen.

Kommentare  
0 Kommentare vorhanden
0 Trackbacks/Pingbacks vorhanden
Du bist herzlich eingeladen auch ein Kommentar zu hinterlassen!
Kommentar schreiben

Vielen Dank für dein Kommentar!