1、HTML

 <!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Template • TodoMVC</title>
<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css">
<!-- CSS overrides - remove if you don't need it -->
<link rel="stylesheet" href="css/app.css">
</head>
<body ng-app="MyTodoMvc">
<section class="todoapp" ng-controller="MainController">
<header class="header">
<h1>todos</h1>
<form ng-submit="add()">
<input class="new-todo" placeholder="What needs to be done?" ng-model="text" autofocus>
</form>
</header>
<section class="main">
<input class="toggle-all" type="checkbox" ng-click="toggleAll()">
<label for="toggle-all">Mark all as complete</label>
<ul class="todo-list">
<li ng-repeat="todo in todos | filter: selector : equalCompare" ng-class="{completed:todo.completed,editing:todo.id===currentEditingId}" data-id="{{todo.id}}">
<div class="view">
<input class="toggle" type="checkbox" ng-model="todo.completed">
<label ng-dblclick="editing(todo.id)">{{todo.text}}</label>
<button class="destroy" ng-click="remove(todo.id)"></button>
</div>
<form ng-submit="save()">
<input class="edit" ng-model="todo.text" ng-blur="save()">
</form>
</li>
</ul>
</section>
<!-- This footer should hidden by default and shown when there are todos -->
<footer class="footer">
<!-- This should be `0 items left` by default -->
<span class="todo-count"><strong>{{todos.length}}</strong> item left</span>
<!-- Remove this if you don't implement routing -->
<ul class="filters">
<li>
<a ng-class="{selected:$location.path() == '/'}" href="#/">All</a>
</li>
<li>
<a ng-class="{selected:$location.path() == '/active'}" href="#/active">Active</a>
</li>
<li>
<a ng-class="{selected:$location.path() == '/completed'}" href="#/completed">Completed</a>
</li>
</ul>
<!-- Hidden if no completed items are left ↓ -->
<button class="clear-completed" ng-click="clear()" ng-show="existCompleted()">Clear completed</button>
</footer>
</section>
<footer class="info">
<p>Double-click to edit a todo</p>
<!-- Remove the below line ↓ -->
<p>Template by <a href="http://sindresorhus.com">Sindre Sorhus</a></p>
<!-- Change this out with your name and url ↓ -->
<p>Created by <a href="http://todomvc.com">you</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<!-- Scripts here. Don't remove ↓ -->
<script src="node_modules/angular/angular.js"></script>
<script src="js/app.js"></script>
</body>
</html>

2、app.js

 (function(angular) {
'use strict'; // 1. 为应用程序创建一个模块,用来管理界面的结构
var myApp = angular.module('MyTodoMvc', []); // 2. 注册一个主要的控制器(属于某个模块),用于往视图(view)中暴露数据
myApp.controller('MainController', ['$scope', '$location', function($scope, $location) {
// [1,2,3,4,5]
// 获取唯一ID
function getId() {
var id = Math.random(); // 1 2
for (var i = 0; i < $scope.todos.length; i++) {
if ($scope.todos[i].id === id) {
id = getId();
break;
}
}
return id;
} // 文本框需要一个模型,为了拿到文本输入的值
$scope.text = ''; // 任务列表也需要一个
// 每一个任务的结构 { id: 1, text: '学习', completed: true }
$scope.todos = [{
id: 0.123,
text: '学习',
completed: false
}, {
id: 0.22,
text: '睡觉',
completed: false
}, {
id: 0.232,
text: '打豆豆',
completed: true
}]; // 添加todo
$scope.add = function() {
if (!$scope.text) {
return;
}
$scope.todos.push({
// 自动增长?
id: getId(),
// 由于$scope.text是双向绑定的,add同时肯定可以同他拿到界面上的输入
text: $scope.text,
completed: false
});
// 清空文本框
$scope.text = '';
}; // 处理删除
$scope.remove = function(id) {
// 删除谁
for (var i = 0; i < $scope.todos.length; i++) {
if ($scope.todos[i].id === id) {
$scope.todos.splice(i, 1);
break;
}
}
// $scope.todos
}; // 清空已完成
$scope.clear = function() {
var result = [];
for (var i = 0; i < $scope.todos.length; i++) {
if (!$scope.todos[i].completed) {
result.push($scope.todos[i]);
}
}
$scope.todos = result;
}; // 是否有已经完成的
$scope.existCompleted = function() {
// 该函数一定要有返回值
for (var i = 0; i < $scope.todos.length; i++) {
if ($scope.todos[i].completed) {
return true;
}
}
return false;
}; // 当前编辑哪个元素
$scope.currentEditingId = -1;
// -1代表一个肯定不存在的元素,默认没有任何被编辑
$scope.editing = function(id) {
$scope.currentEditingId = id;
};
$scope.save = function() {
$scope.currentEditingId = -1;
}; // $scope.checkall = false;
// $scope.$watch('checkall', function(now, old) {
// for (var i = 0; i < $scope.todos.length; i++) {
// $scope.todos[i].completed = now;
// }
// }); var now = true;
$scope.toggleAll = function() {
for (var i = 0; i < $scope.todos.length; i++) {
$scope.todos[i].completed = now;
}
now = !now;
} // 状态筛选
$scope.selector = {}; // {} {completed:true} {completed:false}
// 点击事件的方式不合适,有DOM操作
// 让$scope也有一个指向$location的数据成员
$scope.$location = $location;
// watch只能监视属于$scope的成员
$scope.$watch('$location.path()', function(now, old) {
// 1. 拿到锚点值
// 这样写就要求执行环境必须要有window对象
// var hash = window.location.hash;
// console.log($location);
// console.log(now);
// 2. 根据锚地值对selector做变换
switch (now) {
case '/active':
$scope.selector = { completed: false };
break;
case '/completed':
$scope.selector = { completed: true };
break;
default:
$scope.selector = {};
break;
}
}); // 自定义比较函数, 默认filter过滤器使用的是模糊匹配
$scope.equalCompare = function(source, target) {
// console.log(source);
// console.log(target);
// return false;
return source === target;
}; }]); })(angular);

todomvc-app的更多相关文章

  1. AngularJS的学习--TodoMVC的分析

    最近一段时间一直在看AngularJS,趁着一点时间总结一下. 官网地址:http://angularjs.org/ 先推荐几个教程 1. AngularJS入门教程 比较基础,是官方Tutorial ...

  2. Yeoman 官网教学案例:使用 Yeoman 构建 WebApp

    STEP 1:设置开发环境 与yeoman的所有交互都是通过命令行.Mac系统使用terminal.app,Linux系统使用shell,windows系统可以使用cmder/PowerShell/c ...

  3. 看AngularJS

    最近一段时间一直在看AngularJS,趁着一点时间总结一下. 官网地址:http://angularjs.org/ 先推荐几个教程 1. AngularJS入门教程 比较基础,是官方Tutorial ...

  4. 摆脱DOM操作,从TodoMVC看angularJS

    取代jQuery? 我很久之前便听说了angularJS的大名,之前的leader也经常感叹angularJS的设计如何如何精妙,可叹一直没有机会深入了解,国庆长假因为没钱出游,倒是可以对他做一个了解 ...

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

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

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

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

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

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

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

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

  9. 以todomvc为例分析knockout、backbone和angularjs

    一.整体结构 项目github地址https://github.com/tastejs/todomvc/ 排除通用的css样式文件和引用的js库文件,仅看html和js 1.1 knockoutjs版 ...

  10. 用KnockoutJS实现ToDoMVC代码分析

    体验地址 Knockout 版todo web app在线体验 http://todomvc.com/examples/knockoutjs/ 源码地址 项目源码地址,此地址包含了各种JS框架实现的t ...

随机推荐

  1. fiddler抓包工具教程

    Fiddler是一个蛮好用的抓包工具,可以将网络传输发送与接受的数据包进行截获.重发.编辑.转存等操作.也可以用来检测网络安全.反正好处多多,举之不尽呀!当年学习的时候也蛮费劲,一些蛮实用隐藏的小功能 ...

  2. python迭代器的内置函数

    1.迭代器: 内置函数: (1)iter() -__iter__() (2)next() -__next__() 2.迭代器的举例; 对于Fibs数列,我们对其进行 限量输出: 实现代码如下: cla ...

  3. kali虚拟机安装后操作[配置ssh,安装vmtools,更新源]

    更新源 # 打开控制台, 输入以下命令打开编辑器修改配置文件 $ leafpad /etc/apt/sources.list #kali官方源 deb http://http.kali.org/kal ...

  4. 离线人脸识别 ArcFaceSharp -- ArcFace 2.0 SDK C#封装库分享

    ArcFaceSharp ArcFaceSharp 是ArcSoft 虹软 ArcFace 2.0 SDK 的一个 C# 封装库,为方便进行 C# 开发而封装.欢迎 Start & Fork. ...

  5. mysql和oracle查询出的一条结果中的多个字段拼接

    1,mysql concat('a','b','c')和concat_ws('a','b','c')的区别:前者如果有某个值为空,结果为空;后者如果有某个值为空,可以忽略这个控制 SELECT con ...

  6. BUAAMOOC-Alpha版本发布说明

    BUAAMOOC-Alpha版本发布说明 本说明为BUAAMOOCv1.0版发布说明. 软件截图 上届软件截图 可以看到上届的界面做的很简陋,对于登录.查看课程列表.观看视频等操作需要跳转多个页面,视 ...

  7. 特别好用的eclipse快捷键

    alt+/ 提示 alt+shift+r重命名 alt+shift+j添加文档注释 Ctrl+shift+y小写 Ctrl+shift+x大写 ctrl+shift+f格式化代码(需要取消输入法的简繁 ...

  8. 生命周期事件和 Global.asax 文件

    文章:IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期概述 该文章有介绍Application_Start方法

  9. Unity发布Windows程序遇到的问题

    Unity版本:5.6.2 因为程序中使用了Networking模块,所以在打包发布的时候需要登录Unity的账号,并做设置. 错误信息如下: 解决办法如下: 先登录Unity账号,并在Service ...

  10. iOS- CALayer绘图,如何绘制渐变效果图

    1.渐变效果 —> 色彩空间 首先:自定义一个渐变视图,在自定义视图中重写drawRect #import "ViewController.h" #import " ...