Render Todos page
Learn how to render a view.
The problem
Add a
todosList
property to theAppViewModel
whose default value will be aTodo.List
with the following data:[ { name: "mow lawn", complete: false, id: 5 }, { name: "dishes", complete: true, id: 6 }, { name: "learn canjs", complete: false, id: 7 } ]
Write out an
<li>
for each todo intodosList
, including:- write the todo’s name in the
<label>
- add
completed
in the<li>
’sclass
if the todo iscomplete
. - check the todo’s checkbox if the todo is
complete
.
- write the todo’s name in the
Write out the number of items left and completed count in the “Clear completed” button.
What you need to know
CanJS uses stache to render data in a template and keep it live. Templates can be loaded with steal-stache.
A stache template uses {{key}} magic tags to insert data into the HTML output like:
{{something.name}}
Use {{#if(value)}} to do
if/else
branching incan-stache
.Use {{#for(of)}} to do looping in
can-stache
.
The solution
Click to see the solution
Update index.js to the following:
// index.js
import {Component} from "can";
import view from "./index.stache";
import Todo from "~/models/todo";
import test from "can-todomvc-test";
Component.extend({
tag: "todo-mvc",
view,
ViewModel: {
appName: {default: "TodoMVC"},
todosList: {
default: function(){
return new Todo.List([
{ name: "mow lawn", complete: false, id: 5 },
{ name: "dishes", complete: true, id: 6 },
{ name: "learn canjs", complete: false, id: 7 }
]);
}
}
}
});
const appVM = window.appVM = document.querySelector("todo-mvc").viewModel;
test(appVM);
Update index.stache to the following:
<!-- index.stache -->
<section id="todoapp">
<header id="header">
<h1>{{ this.appName }}</h1>
<input id="new-todo" placeholder="What needs to be done?">
</header>
<section id="main" class="">
<input id="toggle-all" type="checkbox">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list">
{{# for(todo of this.todosList) }}
<li class="todo {{# if(todo.complete) }}completed{{/ if }}">
<div class="view">
<input class="toggle" type="checkbox"
{{# if(todo.complete) }}checked{{/ if }} />
<label>{{ todo.name }}</label>
<button class="destroy"></button>
</div>
<input class="edit" type="text" value="{{ todo.name }}" />
</li>
{{/ for }}
</ul>
</section>
<footer id="footer" class="">
<span id="todo-count">
<strong>{{ this.todosList.active.length }}</strong> items left
</span>
<ul id="filters">
<li>
<a class="selected" href="#!">All</a>
</li>
<li>
<a href="#!active">Active</a>
</li>
<li>
<a href="#!completed">Completed</a>
</li>
</ul>
<button id="clear-completed">
Clear completed ({{ this.todosList.complete.length }})
</button>
</footer>
</section>