Define Todo List page
Define Todo.List type (DefineList basics)
The problem
- Define a 
Todo.Listtype on the export of models/todo.js, where:- It is a DefineList type.
 - The enumerable indexes are coerced into 
Todotypes. - Its 
.activeproperty returns a filteredTodo.Listof the todos that are not complete. - Its 
.completeproperty returns a filteredTodo.Listof the todos that are complete. - Its 
.allCompleteproperty true if all the todos are complete. 
 
Example test code:
QUnit.ok(Todo.List, "Defined a List");
const todos = new Todo.List([
  {complete: true},
  {},
  {complete: true}
]);
QUnit.ok(todos[0] instanceof Todo, "each item in a Todo.List is a Todo");
QUnit.equal(todos.active.length, 1);
QUnit.equal(todos.complete.length, 2);
QUnit.equal(todos.allComplete, false, "not allComplete");
todos[1].complete = true;
QUnit.equal(todos.allComplete, true, "allComplete");
What you need to know
DefineList.extend defines a new
ListType.The # property defines the behavior of items in a list like:
DefineList.extend({ "#": {type: ItemType} })The get behavior defines observable computed properties like:
DefineMap.extend({ propertyName: { get: function() { return this.otherProperty; } } })filter can be used to filter a list into a new list:
list = new ListType([ // ... ]); list.filter(function(item) { return test(item); })
The solution
Click to see the solution
Update models/todo.js to the following:
// models/todo.js
import {DefineMap, DefineList} from "can";
const Todo = DefineMap.extend("Todo", {
    id: "string",
    name: "string",
    complete: {
        type: "boolean",
        default: false
    },
    toggleComplete() {
        this.complete = !this.complete;
    }
});
Todo.List = DefineList.extend("TodoList", {
    "#": Todo,
    get active() {
        return this.filter({
            complete: false
        });
    },
    get complete() {
        return this.filter({
            complete: true
        });
    },
    get allComplete() {
        return this.length === this.complete.length;
    }
});
export default Todo;