backbone todo example
<!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的更多相关文章
- TodoMVC中的Backbone+MarionetteJS+RequireJS例子源码分析之二 数据处理
当我们使用jQuery时大部分时间是聚焦于Dom节点的处理,给Dom节点绑定事件等等:前端mvc框架backbone则如何呢? M-Model,Collection等,是聚焦于数据的处理,它把与后台数 ...
- Django+Tastypie作后端,RequireJS+Backbone作前端的TodoMVC
一.配置好环境 接着前一篇的例子,顺带测试一下已下载下来example里面的backbone_require的例子 注意:直接本地用backbone.localStorage插件运行TodoMVC会报 ...
- Backbone.js之Todo源码浅析
相信每个接触了解过backbone的人都知道todo,网上的关于它的分析教程也都分析乱了.但是,知识只有自己学习领悟才是自己的,话不多说,正文开始. 在分析todo的源码之前,首先我们要知道todo具 ...
- 前端MVC框架Backbone 1.1.0源码分析(一)
前言 如何定义库与框架 前端的辅助工具太多太多了,那么我们是如何定义库与框架? jQuery是目前用的最广的库了,但是整体来讲jQuery目的性很也明确针对“DOM操作”,当然自己写一个原生态方法也能 ...
- 我对Backbone.js的一些认识
backbone.js已经不是当前最流行的前端框架了,但是对于我而言,依然具有比较好的学习价值.虽然目前来说,react,vue等mvvm框架非常火热,但是感觉自身还不到去使用这种框架的层次.这些技术 ...
- backbone学习总结(二)
今天来看下backbone的路由控制的功能.其实个人感觉backbone,模块就那么几个,熟悉它的框架结构,以及组成,就差不多. 废话不多说,我们来看看还剩下的功能. 关于路由和历史管理 通过 Bac ...
- TodoMVC中的Backbone+MarionetteJS+RequireJS例子源码分析之三 Views
这个版本的TodoMVC中的视图组织划分比较细,更加易于理解,这也得益于Marionette为我们带来了丰富的视图选择,原生的backbone只有views,而Marionette则有itemview ...
- TodoMVC中的Backbone+MarionetteJS+RequireJS例子源码分析之一
Marionette牵线木偶,Backbone是脊骨的意思,Marionette是基于Backbone做扩展库,可以理解为把脊骨骨架绑线扯着变成牵线木偶动起来哈哈,使backbone更易使用呵呵! 构 ...
- Django+Tastypie作后端,Backbone作前端的TodoMVC
TodoMVC是各种js框架入门的比较经典的例子,详细可查看github地址https://github.com/tastejs/todomvc 接着上篇文章, 1,先在github上把backbon ...
随机推荐
- 【Python】Eclipse和pydev搭建Python开发环境
参考资料: http://www.dotnet120.com/page/10545/ 1.准备工作: 下载32位的JDK6 Java的开发包 下载 ...
- ToolStripButton样式
public static class Extensions { public static void SetMouseDownStyle(this ToolStripButton button) { ...
- UML交互图(转载)
概述: 从名字交互作用很明显,图中是用来描述一些不同的模型中的不同元素之间的相互作用.所以,这种相互作用是动态行为的系统的一部分. 这种互动行为表示UML中的两个图,被称为序列图和协作图.这两个图的基 ...
- 较复杂js的书写格式
我们看较复杂的js程序最怕结构混乱,一个好的js书写结构,在很大程度上可以减缓阅读的障碍性. 我感觉一个良好的结构要有两点:一是要有一个统一的入口,这样就保证了程序的可阅读性:二是要能够灵活的设置参数 ...
- Ruby中的语句中断和返回
李哲 - APRIL 28, 2015 return,break,next 这几个关键字的使用都涉及到跳出作用域的问题,而他们的不同 则在于不同的关键字跳出去的目的作用域的不同,因为有代码块则导致有一 ...
- 如何说服你的老板必须使用APM?
APM研究院 2015/04/24 16:56 2013年,某权威机构提供一组数据显示:亚马逊每100毫秒延迟会使销售额下降1%:雅虎一秒钟服务器延迟导致收入下降2.8%:谷歌搜索结果页面放缓100毫 ...
- SQL技术内幕-4 row_number() over( partition by XX order by XX)的用法(区别于group by 和order by)
partition by关键字是分析性函数的一部分,它和聚合函数不同的地方在于它能返回一个分组中的多条记录,而聚合函数一般只有一条反映统计值的记录,partition by用于给结果集分组,如果没有指 ...
- POJ 2007 Scrambled Polygon (简单极角排序)
题目链接 题意 : 对输入的点极角排序 思路 : 极角排序方法 #include <iostream> #include <cmath> #include <stdio. ...
- [你必须知道的.NET]第三十五回,判断dll是debug还是release,这是个问题
发布日期:2009.12.29 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 问题的提出 晚上翻着群里的聊天,发现一个有趣的问题:如何通过编码 ...
- loadrunner之Paramater在负载测试中的数据生成规则
前段时间在做性能测试的时候,基于业务的需求,使用到了Unique Number的参数类型. 脚本的业务是注册以alien开头,后面接数字的用户帐号,填写相关帐号信息.提交企业信息进行审核. 其中用户帐 ...