1) 将鼠标切换到要创建项目的目录
2) ng new 项目名
--创建新的项目
3) 在下载开始后之后,使用Ctrl+C打断:cd进入到刚刚创建项目当中,使用 cnpm install
来进行安装(注意时机,要在下载开始后打断,目的是使用国内镜像下载)(进入之后开始下载)
4)下载完成之后(可以通过目录变化看到已经下载好的第三方包) 使用npm start
启动,占用4200端口
5)打开浏览器之后的看到首页
1) 下载模板粘贴相应内容到应用的模板首页中,即app.component.html中
2) 在终端中下载模板中会用的css文件等,可以使用电脑终端,也可以使用自带VSCode的终端
cnpm install todomvc-common todomvc-app-css
3) 组件可以有自己的样式,也可以有全局样式;所以我们可以将组件添加到app.component .css中,也可以添加到src目录下的styles.css样式中;在文件中使用@import url('样式名字')
;这里我写到styles.css中
@import url('todomvc-common/base.css');
@import url('todomvc-app-css/index.css');
4)在ts文件中添加我们要在模板上展示的数据:在.ts文件中定义数组,初始化数据的值 ;然后在HTML文件中进行循环遍历将数据展示在页面上;
const todos=[{
id: 1,
title: '吃饭',
done: true
}]
...
export class AppComponent {
public todos: {
id: number,
title: string,
done: boolean
}[]=todos
}
<ul class="todo-list">
<li *ngFor="let todo of filterTodos">
<div class="view">
<input class="toggle" type="checkbox" [(ngModel)]="todo.done">
<label>{{ todo.title }}</label>
<button class="destroy""></button>
</div>
<input class="edit">
</li>
</ul>
5)回车的时候todo项保存
<input class="new-todo"
placeholder="What needs to be done?"
autofocus
(keyup.enter)="addTodo($event)">
addTodo(e):void{
const titleText=e.target.value;
if(!titleText.length){
return;
}
const last=this.todos[this.todos.length];
this.todos.push({
id: last?last.id+1:1,
title: titleText,
done: false
})
//添加事件之后清除文本框内容
e.target.value='';
}
6)某个todo项完成之后样式发生改变, (completed是样式,[ngClass]绑定之后, 如果todo.done为true就会添加completed样式). 注意这个表单项要在app.module.ts文件中导入相应的表单项, 然后再倒入项中声明
import { FormsModule } from '@angular/forms'
....
@NgModule({
...
imports: [
...
FormsModule
],
...
})
[ngClass]="{completed: todo.done,}">
<div class="view">
<input class="toggle"
type="checkbox"
[(ngModel)]="todo.done">
<button class="destroy"></button>
</div>
import { FormsModule } from '@angular/forms'
...
imports: [
BrowserModule,
AppRoutingModule,
FormsModule //加入
]
7)所有todo项全部完成之后复选框选中, 当所有的todo项完成的时候toggleAll()使用get取值返回为true,那么复选框选中,返回为false的时候复选框不选中
[checked]="toggelAll" //input标签
get toggelAll() {
return this.todos.every(t=>t.done)
}
8)复选框选中的时候所有todo项选中,反之不选中,当change事假发生的时候触发toggelAll,后面的数据作为参数传递到toggelAll方法中,遍历设置所有的todo项的属性
(change)="toggelAll=$event.target.checked"
set toggelAll(val){
this.todos.forEach(t=>t.done=val)
}
9)删除单个:在html 中定义遍历索引项,之后绑定方法,在ts文件中定义
<button class="destroy" (click)="removeTodo(i)"></button>
removeTodo(index: number): void {
this.todos.splice(index, 1)
}
10)双击label变成编辑模式,双击label使currentEditing等于data,两者相等时.已经绑定的当前的todo与中间变量相等的时候就添加编辑样式,进入编辑模式
<li *ngFor="let todo of filterTodos; let i = index;"
[ngClass]="{..
editing: currentEditing === todo }">
<div class="view">
...
<label (dblclick)="currentEditing = todo">{{ todo.title }}</label>
...
</li>
public currentEditing: {
id: number,
title: string,
done: boolean
} = null
handleEditKeyUp(e) {
const { keyCode, target } = e
if (keyCode === 27) {
// 取消编辑
// 同时把文本框的值恢复为原来的值
target.value = this.currentEditing.title
//currentEditing是中间变量
this.currentEditing = null
}
}
11)编辑内容之后点击enter进行保存
<input class="edit" [value]="todo.title" (keyup)="handleEditKeyUp($event)"
(keyup.enter)="saveEdit(todo, $event)">
saveEdit(todo, e) {
// 保存编辑
todo.title = e.target.value
// 去除编辑样式
this.currentEditing = null
}
12) 按Esc退出编辑模式,并且不保存内容
<input class="edit" ... (keyup)="handleEditKeyUp($event)" ...>
handleEditKeyUp(e) {
const { keyCode, target } = e
if (keyCode === 27) {
target.value = this.currentEditing.title
this.currentEditing = null
}
}
13)离开焦点之后编辑框的数据也要进行保存, save方法与前面的一样
<input ... (blur)="saveEdit(todo, $event)">
14) 显示所有未完成
<span class="todo-count"><strong>{{ remaningCount }}</strong> item left</span>
get remaningCount() {
return this.todos.filter(t => !t.done).length
}
15) 数据过滤以及显示所有任务/已经完成的任务/未完成的任务
<li *ngFor="let todo of filterTodos; let i = index;" [ngClass]="{
completed: todo.done,
editing: currentEditing === todo
}">
..................
<ul class="filters">
<li>
<a [ngClass]="{selected: visibility === 'all'}" href="#/">All</a>
</li>
<li>
<a [ngClass]="{selected: visibility ==='active'}" href="#/active">Active</a>
</li>
<li>
<a [ngClass]="{selected: visibility === 'completed'}" href="#/completed">Completed</a>
</li>
</ul>
//Angular钩子函数
ngOnInit() {
// 初始化的时候手动调用一次
this.hashchangeHandler()
// 注意:这里要 bind this绑定
window.onhashchange = this.hashchangeHandler.bind(this)
}
hashchangeHandler() {
// 当用户点击了锚点的时候,我们需要获取当前的锚点标识
// 然后动态的将根组件中的 visibility 设置为当前点击的锚点标识
const hash = window.location.hash.substr(1)
switch (hash) {
case '/':
this.visibility = 'all'
break;
case '/active':
this.visibility = 'active'
break;
case '/completed':
this.visibility = 'completed'
break;
}
}
get filterTodos() {
if (this.visibility === 'all') {
return this.todos
} else if (this.visibility === 'active') {
return this.todos.filter(t => !t.done)
} else if (this.visibility === 'completed') {
return this.todos.filter(t => t.done)
}
}
15) 清除所有
<button (click)="clearAllDone()" class="clear-completed">Clear completed</button>
clearAllDone() {
this.todos = this.todos.filter(t => !t.done)
}
16) 利用钩子函数将数据持久化到本地
//初始化变量的时候
public todos: {
id: number,
title: string,
done: boolean
}[] = JSON.parse(window.localStorage.getItem('todos') || '[]')
ngDoCheck() {
window.localStorage.setItem('todos', JSON.stringify(this.todos))
}
更多细节内容可以参考http://todomvc.com/