bitovi/canjs

View on GitHub
demos/can-connect/fall-through-cache.html

Summary

Maintainability
Test Coverage
<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>