<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
html,
body {
margin: 0;
padding: 0;
} body {
font: 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #eeeeee;
color: #333333;
width: 520px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
} #todoapp {
background: #fff;
padding: 20px;
margin-bottom: 40px;
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
-ms-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
-webkit-border-radius: 0 0 5px 5px;
-moz-border-radius: 0 0 5px 5px;
-ms-border-radius: 0 0 5px 5px;
-o-border-radius: 0 0 5px 5px;
border-radius: 0 0 5px 5px;
} #todoapp h1 {
font-size: 36px;
font-weight: bold;
text-align: center;
padding: 0 0 10px 0;
} #todoapp input[type="text"] {
width: 466px;
font-size: 24px;
font-family: inherit;
line-height: 1.4em;
border: 0;
outline: none;
padding: 6px;
border: 1px solid #999999;
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-ms-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
} #todoapp input::-webkit-input-placeholder {
font-style: italic;
} #main {
display: none;
} #todo-list {
margin: 10px 0;
padding: 0;
list-style: none;
} #todo-list li {
padding: 18px 20px 18px 0;
position: relative;
font-size: 24px;
border-bottom: 1px solid #cccccc;
} #todo-list li:last-child {
border-bottom: none;
} #todo-list li.done label {
color: #777777;
text-decoration: line-through;
} #todo-list .destroy {
position: absolute;
right: 5px;
top: 20px;
display: none;
cursor: pointer;
width: 20px;
height: 20px;
background: orange;
border-radius: 10px;
} #todo-list li:hover .destroy {
display: block;
} #todo-list .destroy:hover {
background-position: 0 -20px;
} #todo-list li.editing {
border-bottom: none;
margin-top: -1px;
padding: 0;
} #todo-list li.editing:last-child {
margin-bottom: -1px;
} #todo-list li.editing .edit {
display: block;
width: 444px;
padding: 13px 15px 14px 20px;
margin: 0;
} #todo-list li.editing .view {
display: none;
} #todo-list li .view label {
word-break: break-word;
} #todo-list li .edit {
display: none;
} #todoapp footer {
display: none;
margin: 0 -20px -20px -20px;
overflow: hidden;
color: #555555;
background: #f4fce8;
border-top: 1px solid #ededed;
padding: 0 20px;
line-height: 37px;
-webkit-border-radius: 0 0 5px 5px;
-moz-border-radius: 0 0 5px 5px;
-ms-border-radius: 0 0 5px 5px;
-o-border-radius: 0 0 5px 5px;
border-radius: 0 0 5px 5px;
} #clear-completed {
float: right;
line-height: 20px;
text-decoration: none;
background: rgba(0, 0, 0, 0.1);
color: #555555;
font-size: 11px;
margin-top: 8px;
margin-bottom: 8px;
padding: 0 10px 1px;
cursor: pointer;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
-ms-border-radius: 12px;
-o-border-radius: 12px;
border-radius: 12px;
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
-ms-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
} #clear-completed:hover {
background: rgba(0, 0, 0, 0.15);
-webkit-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
-moz-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
-ms-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
-o-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
} #clear-completed:active {
position: relative;
top: 1px;
} #todo-count span {
font-weight: bold;
} #instructions {
margin: 10px auto;
color: #777777;
text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
text-align: center;
} #instructions a {
color: #336699;
} #credits {
margin: 30px auto;
color: #999;
text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
text-align: center;
} #credits a {
color: #888;
}
</style>
</head>
<body>
<div id="todoapp"> <header>
<h1>Todos</h1>
<input id="new-todo" type="text" placeholder="What needs to be done?">
</header> <section id="main">
<input id="toggle-all" type="checkbox">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list"></ul>
</section> <footer>
<a id="clear-completed">Clear completed</a>
<div id="todo-count"></div>
</footer> </div> <div id="instructions">
Double-click to edit a todo.
</div> <!-- Templates --> <script type="text/template" id="item-template">
<div class="view">
<input class="toggle" type="checkbox" <%= done ? 'checked="checked"' : '' %> />
<label><%- title %></label>
<a class="destroy"></a>
</div>
<input class="edit" type="text" value="<%- title %>" />
</script> <script type="text/template" id="stats-template">
<% if (done) { %>
<a id="clear-completed">Clear <%= done %> completed <%= done == 1 ? 'item' : 'items' %></a>
<% } %>
<div class="todo-count"><b><%= remaining %></b> <%= remaining == 1 ? 'item' : 'items' %> left</div>
</script> <script src="lib/json2.js"></script>
<script src="lib/jquery-latest.js"></script>
<script src="lib/underscore.js"></script>
<script src="lib/backbone.js"></script>
<script src="lib/backbone.localStorage.js"></script>
<script src="js/demo20.js"></script>
</body>
</html>
$(function(){
var Todo = Backbone.Model.extend({
defaults: function() {
return {
title: "empty todo...",
order: Todos.nextOrder(),
done: false
};
}, initialize: function() {
if (!this.get("title")) {
this.set({"title": this.defaults().title});
}
}, toggle: function() {
this.save({done: !this.get("done")});
} }); var TodoList = Backbone.Collection.extend({ model: Todo, localStorage: new Backbone.LocalStorage("todos-backbone"), done: function() {
return this.filter(function(todo){ return todo.get('done'); });
}, remaining: function() {
return this.without.apply(this, this.done());
}, nextOrder: function() {
if (!this.length) return 1;
return this.last().get('order') + 1;
}, comparator: function(todo) {
return todo.get('order');
} }); var Todos = new TodoList; var TodoView = Backbone.View.extend({ tagName: "li", template: _.template($('#item-template').html()), events: {
"click .toggle" : "toggleDone",
"dblclick .view" : "edit",
"click a.destroy" : "clear",
"keypress .edit" : "updateOnEnter",
"blur .edit" : "close"
}, initialize: function() {
this.listenTo(this.model, 'change', this.render);
this.listenTo(this.model, 'destroy', this.remove);
}, render: function() {
this.$el.html(this.template(this.model.toJSON()));
this.$el.toggleClass('done', this.model.get('done'));
this.input = this.$('.edit');
return this;
}, toggleDone: function() {
this.model.toggle();
}, edit: function() {
this.$el.addClass("editing");
this.input.focus();
}, close: function() {
var value = this.input.val();
if (!value) {
this.clear();
} else {
this.model.save({title: value});
this.$el.removeClass("editing");
}
}, updateOnEnter: function(e) {
if (e.keyCode == 13) this.close();
}, clear: function() {
this.model.destroy();
} }); var AppView = Backbone.View.extend({ el: $("#todoapp"), statsTemplate: _.template($('#stats-template').html()), events: {
"keypress #new-todo": "createOnEnter",
"click #clear-completed": "clearCompleted",
"click #toggle-all": "toggleAllComplete"
}, initialize: function() { this.input = this.$("#new-todo");
this.allCheckbox = this.$("#toggle-all")[0]; this.listenTo(Todos, 'add', this.addOne);
this.listenTo(Todos, 'reset', this.addAll);
this.listenTo(Todos, 'all', this.render); this.footer = this.$('footer');
this.main = $('#main'); Todos.fetch();
}, render: function() {
var done = Todos.done().length;
var remaining = Todos.remaining().length; if (Todos.length) {
this.main.show();
this.footer.show();
this.footer.html(this.statsTemplate({done: done, remaining: remaining}));
} else {
this.main.hide();
this.footer.hide();
} this.allCheckbox.checked = !remaining;
}, addOne: function(todo) {
var view = new TodoView({model: todo});
this.$("#todo-list").append(view.render().el);
}, addAll: function() {
Todos.each(this.addOne, this);
}, createOnEnter: function(e) {
if (e.keyCode != 13) return;
if (!this.input.val()) return; Todos.create({title: this.input.val()});
this.input.val('');
}, clearCompleted: function() {
_.invoke(Todos.done(), 'destroy');
return false;
}, toggleAllComplete: function () {
var done = this.allCheckbox.checked;
Todos.each(function (todo) { todo.save({'done': done}); });
} }); var App = new AppView;
});

backbone todo example的更多相关文章

  1. TodoMVC中的Backbone+MarionetteJS+RequireJS例子源码分析之二 数据处理

    当我们使用jQuery时大部分时间是聚焦于Dom节点的处理,给Dom节点绑定事件等等:前端mvc框架backbone则如何呢? M-Model,Collection等,是聚焦于数据的处理,它把与后台数 ...

  2. Django+Tastypie作后端,RequireJS+Backbone作前端的TodoMVC

    一.配置好环境 接着前一篇的例子,顺带测试一下已下载下来example里面的backbone_require的例子 注意:直接本地用backbone.localStorage插件运行TodoMVC会报 ...

  3. Backbone.js之Todo源码浅析

    相信每个接触了解过backbone的人都知道todo,网上的关于它的分析教程也都分析乱了.但是,知识只有自己学习领悟才是自己的,话不多说,正文开始. 在分析todo的源码之前,首先我们要知道todo具 ...

  4. 前端MVC框架Backbone 1.1.0源码分析(一)

    前言 如何定义库与框架 前端的辅助工具太多太多了,那么我们是如何定义库与框架? jQuery是目前用的最广的库了,但是整体来讲jQuery目的性很也明确针对“DOM操作”,当然自己写一个原生态方法也能 ...

  5. 我对Backbone.js的一些认识

    backbone.js已经不是当前最流行的前端框架了,但是对于我而言,依然具有比较好的学习价值.虽然目前来说,react,vue等mvvm框架非常火热,但是感觉自身还不到去使用这种框架的层次.这些技术 ...

  6. backbone学习总结(二)

    今天来看下backbone的路由控制的功能.其实个人感觉backbone,模块就那么几个,熟悉它的框架结构,以及组成,就差不多. 废话不多说,我们来看看还剩下的功能. 关于路由和历史管理 通过 Bac ...

  7. TodoMVC中的Backbone+MarionetteJS+RequireJS例子源码分析之三 Views

    这个版本的TodoMVC中的视图组织划分比较细,更加易于理解,这也得益于Marionette为我们带来了丰富的视图选择,原生的backbone只有views,而Marionette则有itemview ...

  8. TodoMVC中的Backbone+MarionetteJS+RequireJS例子源码分析之一

    Marionette牵线木偶,Backbone是脊骨的意思,Marionette是基于Backbone做扩展库,可以理解为把脊骨骨架绑线扯着变成牵线木偶动起来哈哈,使backbone更易使用呵呵! 构 ...

  9. Django+Tastypie作后端,Backbone作前端的TodoMVC

    TodoMVC是各种js框架入门的比较经典的例子,详细可查看github地址https://github.com/tastejs/todomvc 接着上篇文章, 1,先在github上把backbon ...

随机推荐

  1. Python字符编码详解

    1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Information Interchange),是一种单字节的编码.计算机世界里一开始只有 ...

  2. php图形图像处理之生成验证码

    \(^o^)/~ 现在网上越来越离不开验证码了,不知道小伙伴们知不知利用php的GD库就可以生成验证码,Σ(⊙▽⊙"a ...... 首先介绍几个需要用的函数. 1.imagesetpixe ...

  3. Oracle中定义package以及存储过程的使用

    使用scott账户下的dept表: select * from dept order by deptno; 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 30 S ...

  4. XStream使用详解

    1.Xstream介绍 (1)Xstream介绍     Xstream是一种OXMapping 技术,是用来处理XML文件序列化的框架,在将JavaBean序列化,或将XML文件反序列化的时候,不需 ...

  5. 【Ubuntu】NAT配置

    1.简介 2.配置 1.简介 NAT(Network Address Translation,网络地址转换)是将IP 数据包头中的IP 地址转换为另一个IP 地址的过程.在实际应用中,NAT 主要用于 ...

  6. LAMP环境的搭建

    [一些前言废话]一名web开发尤其是后端不懂LAMP环境的搭建,那就摊上事了,有些人说他一直用win下的wampServer这种傻瓜式环境搭建,用的挺好的,也有人说他用云服务器,搭配“一键搭建LAMP ...

  7. Json Serialize 忽略特定属性

    Json Serialize 忽略特定属性 Json Serialize SerializeFilter 忽略特定属性 key words:Json Serialize jackson fastjso ...

  8. Leetcode#126 Word Ladder II

    原题地址 既然是求最短路径,可以考虑动归或广搜.这道题对字典直接进行动归是不现实的,因为字典里的单词非常多.只能选择广搜了. 思路也非常直观,从start或end开始,不断加入所有可到达的单词,直到最 ...

  9. PE文件结构深入详解

    一.PE结构基础 看了很多PE结构类的东东,要不上来就是整体结构,要不就是一大堆ASM代码,看的我等菜鸟有点难受!所以自己写个帖·学习PE我们先来弄懂几个问题! 1:几个地址的概念 VA:虚拟地址,也 ...

  10. XHProf的安装和使用(PHP性能测试神器)

    XHProf是Facebook开发的性能调试工具,帮助我们的PHP程序性能调优,更加健壮.XHProf安装和使用方法将在本章讲解.XHProf是PHP的PECL扩展.没有XDeBug那些耗费资源,更加 ...