demos/can-connect/fall-through-cache.html
<body>
<a href="#complete">Completed</a>
<a href="#incomplete">Incomplete</a>
<div id='list'></div>
<script>
steal = { forceES5: false };
</script>
<script src="../../node_modules/steal/steal.js" id="demo-source">
import {
connect, fixture, ObservableObject, ObservableArray, Observation,
QueryLogic, domEvents, type, localStore
} from "can";
import $ from "jquery";
import fallThroughCache from "can-connect/fall-through-cache/fall-through-cache";
import dataUrl from "can-connect/data/url/url";
import connectConstructor from "can-connect/constructor/constructor";
import constructorStore from "can-connect/constructor/store/store";
import connectCanMap from "can-connect/can/map/map";
class Todo extends ObservableObject {
static get props() {
return {
id: {type: type.maybeConvert(Number), identity: true},
name: type.maybeConvert(String),
complete: type.maybeConvert(Boolean)
};
}
}
Todo.queryLogic = new QueryLogic(Todo);
class TodoList extends ObservableArray {
static get props() {
return {};
}
static get items() {
return type.maybeConvert(Todo);
}
}
var cache = connect([
localStore
],{
name: "todos",
queryLogic: Todo.queryLogic
});
// A connection that gets todos data
var todosConnection = connect([
fallThroughCache,
dataUrl,
connectConstructor,
constructorStore,
connectCanMap
],{
url: "/todos",
cacheConnection: cache,
Map: Todo,
List: TodoList
});
var todoItem = function(todo) {
var li = $("<li>");
var liUpdate = new Observation(function(){
if(todo.complete) {
li.css("text-decoration","line-through");
} else {
li.css("text-decoration","");
}
li.text(todo.id+": "+todo.name);
});
var handler = function(){};
liUpdate.on(liUpdate)
domEvents.addEventListener(li[0], "removed", function(){
liUpdate.off(liUpdate);
});
li.bind("click", function(){
todo.complete = !todo.complete
});
return li;
};
var todoList = function(set){
var element = $('<ul>Loading</ul>');
var todos;
var add = function(ev, inserted, index) {
var lis = [].map.call(inserted, function(todo){
return todoItem(todo).hide()[0];
});
if(element.children().length > index) {
element.children().eq(index).after( $(lis) );
} else if(element.children().length) {
element.children().last().after( $(lis) );
} else {
element.append($(lis));
}
$(lis).fadeIn();
};
var remove = function(ev, inserted, index) {
var li = element.children().eq( index );
var count = 0;
while(count < inserted.length) {
let cur = li;
li.fadeOut(function(){
cur.remove();
});
li = li.next();
count++;
}
};
todosConnection.getList(set).then(function(retrievedTodos){
element.empty();
todos = retrievedTodos;
todos.on("add", add).on("remove", remove);
//Object.observe(todos, update, ["add", "update", "delete"] );
add({},todos, 0)
});
domEvents.addEventListener(element[0], "removed", function(){
todos.off("add", add).off("remove", remove);
remove([],todos,0);
});
return element;
};
// When the hash changes, update which `todoList` is displayed.
var updatePage = function(){
var complete = window.location.hash !== "#incomplete";
$("#list").children().remove().triggerHandler("remove");
var ul = todoList({filter: {complete: complete }});
$("#list").html(ul);
};
$(window).bind("hashchange", updatePage);
// Trap ajax requests to return a random list of todos
fixture.delay = 1000;
fixture({
"GET /todos": function(request){
var todos = randomTodos(request.data.filter.complete == "true");
return {data: todos};
}
});
function randomTodos(complete){
var verbs = ["do","wash","mow","clean","take out"];
var names = ["dishes","lawn","garbage", "laundry","windows","floor"];
var ids = [];
for(var i =0; i < 10; i++) {
ids.push(i);
}
var todos = [];
var total = fixture.rand(7) + 1;
var randomIds = fixture.rand(ids,total, total);
for(var i = 0; i < total; i++){
todos.push({
id: randomIds[i],
name: fixture.rand(verbs,1)[0]+" "+fixture.rand(names,1)[0],
complete: complete
});
}
return todos;
}
// Kick off current page
updatePage();
</script>
</body>