There are 10 spirals in the [todo_mvc_spirals] (https://github.com/dzenanr/todo_mvc_spirals) project: from todo_mvc_s00 to todo_mvc_s09. The final version is the [dartling_todos] (https://github.com/dzenanr/dartling_todos) application. This post is about todo_mvc_s04.
In the todo_mvc_s04 spiral, tasks (Figure 1) are loaded from a local storage,
![Alt Figure 1: todo_mvc_s04] (/img/todo_mvc_s04/tasks.png)
Figure 1: Loaded tasks.
and saved to the local storage as a [JSON] (http://www.json.org/) document (Code 1). The list represents tasks, and each map { } is a task with four attributes. The oid attribute is generated by dartling and represents an object identifier, which is a unique time stamp. The code attribute also comes from dartling, but it is not used in this application.
Code 1: JSON document for tasks.
[
{
"completed":"false",
"oid":"1355408619267",
"title":"explain dartling todos",
"code":null
},
{
"completed":"true",
"oid":"1355412503471",
"title":"explain spiral 03",
"code":null
},
{
"completed":"false",
"oid":"1355412519900",
"title":"explain spiral 04",
"code":null
}
]
There are two new methods in the TodoApp class (Code 2).
Code 2: load and save methods.
load() {
var json = window.localStorage['todos'];
if (json != null) {
try {
var todoList = JSON.parse(json);
for (Map todo in todoList) {
var task = new Task(tasks.concept);
task.fromJson(todo);
add(task);
}
} catch (e) {
window.console.log(
'Could not load todos from the local storage. ${e}');
}
}
}
save() {
window.localStorage['todos'] = JSON.stringify(tasks.toJson());
}
The load method retrieves the text value of the todos key from the local storage. This value, if it exists, is parsed to produce a list of maps. Each map in the list is a task, which is then converted to a dartling object by the fromJson method inherited from the ConceptEntity class of dartling (Code 3). The save method converts a list of tasks to a string. The list is obtained by the toJson method inherited from the Entities class of dartling (Code 3). The two abstract classes (Code 3) located in the lib/gen/todo/mvc/tasks.dart file are generated by dartling. They should not be updated by a programmer to allow a code regeneration if the model changes.
Code 3: Abstract classes for the Task concept of the model.
abstract class TaskGen extends ConceptEntity<Task> {
TaskGen(Concept concept) : super.of(concept);
String get title => getAttribute("title");
set title(String a) => setAttribute("title", a);
bool get completed => getAttribute("completed");
set completed(bool a) => setAttribute("completed", a);
Task newEntity() => new Task(concept);
}
abstract class TasksGen extends Entities<Task> {
TasksGen(Concept concept) : super.of(concept);
Tasks newEntities() => new Tasks(concept);
}
The two specific classes (Code 4) located in the lib/todo/mvc/tasks.dart file are also generated by dartling. However, they may be changed by a programmer to add some specific methods that do not exist in dartling. In this example, the completed and left properties have been added to simplify programming in the application classes.
Code 4: Specific classes for the Task concept of the model.
class Task extends TaskGen {
Task(Concept concept) : super(concept);
}
class Tasks extends TasksGen {
Tasks(Concept concept) : super(concept);
int get completed => select((task) => task.completed).count;
int get left => count - completed;
}
The constructor of the TodoApp class receives now the tasks as its parameter (Code 5). The load method is called at the very beginning of the constructor.
Code 5: Remove element.
TodoApp(this.tasks) {
load();
}
The main function in the todo_mvc.dart file obtains the tasks object from the model entries (Code 6). There is only one entry in the model and only one model in the todo domain, which is contained in the dartling repository.
Code 6: Starting dartling.
main() {
var repo = new TodoRepo();
var todo = repo.getDomainModels(TodoRepo.todoDomainCode);
var mvc = todo.getModelEntries(TodoRepo.todoMvcModelCode);
Tasks tasks = mvc.getEntry('Task');
new TodoApp(tasks);
}
The TodoWidget class is renamed into Todo (Code 7). Task or tasks refer to the model and todo and todos refer to the application. The element property becomes todo and elementToggle is simply toggle.
Code 7: Todo class.
class Todo {
Task task;
TodoApp todoApp;
Element todo;
Element toggle;
Todo(this.task, this.todoApp);
Element createElement() {
todo = new Element.html('''
<li ${task.completed ? 'class="completed"' : ''}>
</li>
''');
}
In the TodoApp class, todoWidgets are now todos (Code 8).
Code 8: TodoApp class.
class TodoApp {
Tasks tasks;
var todos = new List<Todo>();
}