zoukankan      html  css  js  c++  java
  • Angular项目 TodoMVC

    起步

    • 准备

      • 下载静态模板
        • git clone https://github.com/tastejs/todomvc-app-template.git --depth 1
        • 在静态文件根目录下 npm install
      • 初始化项目
        • ng new todomvc-angular
        • 在进行基础的选择之后,ctrl+c打断下载
        • 打开新建的项目目录,CMD进入cnpm install
        • 启动npm start或者ng serve
        • angular后台服务器开启http://localhost:4200/
    • 将静态模板装载到angular脚手架生成的项目文件中

      • 将静态文件中的index.html文件HTML骨架复制粘贴到项目app文件夹下的app.component.html文件中
      • 在项目文件的根目录中引入安装包todomvc-common todomvc-app-css,cnpm i todomvc-common todomvc-app-css
      • 在项目文件根目录中,找到angular.json文件,找到styles全局配置文件路径文件,打开此路径中的文件,引入全局css配置,依赖文件
        • 这里载入的第三方包中的样式文件可以不写路径,直接写第三方包名称路径即可
        • 这里的CSS样式也可以写入局部CSS配置中
        • @import url('todomvc-app-css/index.css');
        • @import url('todomvc-common/base.css');
        • 至此,静态页面完全移植至angular项目中
    • TodoMVC需求说明

      • 数据列表显示
        • 有数据
        • 无数据
      • 添加任务
        • 页面初始化的时候文本框获得焦点
        • 敲回车添加到任务列表中
        • 不允许有非空数据
        • 添加完成清空文本框
      • 标记所有任务完成/未完成
      • 任务项
        • 切换任务完成状态
        • 删除任务项
        • 双击label进入编辑模式
      • 编辑任务项
        • 编辑文本框自动获取焦点
        • 在编辑文本框中敲回车或者失去焦点
        • 输入状态按下esc取消编辑
      • 显示所有未完成任务数
        • 模板逻辑
        • 方法
        • 计算属性
      • 清除所有已完成任务
      • 将数据持久化到localStorage中
      • 路由状态切换
        • 点击链接过滤数据的输出
        • 刷新保持过滤状态
        • 切换点击链接的样式
    • angular列表循环的写法

      • *ngFor = "表达式"
      • <li *ngFor="let todo of todos">{{todo.title}}</li>
    • angular条件渲染

      • *ngIf="todos.length"
      • 若是在某标签中写上为假的判断*ngIf="false",则此标签隐藏
    • angular模板语法之层级包裹

      • 原先写法,在需要的模块架构之上,加上统一的div,然后写上判断语句*ngIf="todos.length"
      • 模板语法:将div改成<ng-template [ngIf]="todos.length"></ng-template>
    <ng-template [ngIf]="todos.length"></ng-template>
    
    • angular事件的写法
      • (keyup.enter)="addTodo($event)"
      • addTodo事件函数中,this指向数据对象,这点和Vue相似,事件指向数据
    <input 
      class="new-todo" 
      placeholder="What needs to be done?" 
      autofocus 
      (keyup.enter)="addTodo($event)"
    >
    
    • angular双向数据绑定
      • 在主模块中引入import { FormsModule } from '@angular/forms';
      • 在主模块下面的依赖列表中加入:FormsModule
      • [(ngModel)]="todo.done"
    <input 
      class="toggle" 
      type="checkbox"
      [(ngModel)]="todo.done"
    >
    
    • angular样式绑定
      • [ngClass]="{completed: todo.done}"
    <li 
      *ngFor="let todo of todos"
      [ngClass]="{completed: todo.done}"
    >
    
    • get set属性存取器
      • get 数据写入页面
        • 当所有的t.done为真时,返回数据true,写入checked中
      • set 数据取出页面
        • 当input状态改变时,将checked的值传入函数,然后子类每项赋值
      // 子开关控制总开关,全选总开关选中
      // 所有的t.done为真时,返回数据,存入checked
      get toggleAll(){
        return this.todos.every(t => t.done)
      }
      // 总开关控制子开关,全选全不选
      // 当总开关触发时`$event.target.checked`
      // 当input状态改变时,将checked的值传入函数,然后每项赋值
      set toggleAll(val){
        this.todos.forEach(t => t.done = val)
      }
    
    • angular获取当前索引
      • 在for循环时,拿下索引变量i
      • 将索引变量传参给事件函数removeTodo(i)
      • 索引函数得到当前索引值
    <li 
      *ngFor="let todo of todos; let i = index;"
      [ngClass]="{completed: todo.done}"
    >
      <button 
        class="destroy"
        (click)='removeTodo(i)'
      ></button>
    </li>
    
    removeTodo(index: number){
      this.todos.splice(index, 1)
      console.log(index);
    }
    
    • 删除当前项方法
      removeTodo(index: number){
        this.todos.splice(index, 1)
      }
    
    • ngClass属性
      • 类名: 布尔判断
    <li 
      *ngFor="let todo of todos; let i = index;"
      [ngClass]="{
        completed: todo.done,
        editing: currentEditing === todo
      }"
    ></li>
    
    • 关于选择当前对象
      • 在循环对象创建中,是一个对象数组
      • 因此,额外的创建一个空对象用来装载当前数据,以索引值为契机
      • 然后,将装载的数据在对象数组中遍历匹配
      • 匹配成功,即为选中当前对象
      • 取消选择,只要将临时的对象清空即可
    const todos = [
      {
        id: 1,
        title: '摄影',
        done: true
      },
      {
        id: 2,
        title: '设计',
        done: true
      },
      {
        id: 3,
        title: '程序',
        done: false
      }
    ]
    // 定义对象数组
    public todos: {
      id: number,
      title: string,
      done: boolean
    }[] = todos
    // 定义匹配对象
    public currentEditing: {
      id: number,
      title: string,
      done: boolean
    } = null
    
    <!-- 将匹配对象在数组对象中遍历寻找,相同即执行 -->
    <li 
      *ngFor="let todo of todos; let i = index;"
      [ngClass]="{
        completed: todo.done,
        editing: currentEditing === todo
      }"
    >
    <!-- 鼠标双击后,将当前值传给匹配对象 -->
    <label
      (dblclick)="currentEditing = todo"
    >{{ todo.title }}</label>
    </li>
    
    • 解构赋值
      • e就是$event的传参
    const {keyCode, target} = e;
    
    • 过滤器
      • 过滤器中的回调函数用箭头函数,可以避免this问题
    get remaningCount(){
      return this.todos.filter(t => !t.done).length
    }
    
    • 获取标签内容

      • e.srcElement.innerHTML
      • e.srcElement.innerText
    • 实现导航切换数据过滤的功能

      public visibility: string = "all"
      get filterTodos(){
        if(this.visibility === 'all'){
          return todos
        }else if(this.visibility === 'active'){
          return todos.filter(t => !t.done)
        }else if(this.visibility === 'completed'){
          return todos.filter(t => t.done)
        }
      }
    
    • 初始化钩子函数

      • 初始化钩子函数 ngOnInit()
      • 该函数是一个特殊的Angular生命周期钩子函数
      • 他会在Anhular应用初始化的时候执行一次
    • 哈希函数

      • 哈希函数即是描点函数
      ngOnInit(){
        // Angular初始化时,监听hash的变化
        // 此处要用箭头函数
        window.onhashchange = () => {
          // 当用户点击锚点时,我们需要获取当前的锚点链接
          // 然后动态的将根组件中的visibility设置为当前点击的锚点标识
          const hash = window.location.hash;
          console.log(hash);
        }
      }
    
    • 实现导航切换数据过滤的功能
      • 提供一个属性,该属性会根据当前点击的链接返回过滤之后的数据
        • filterTodos
      • 提供一个属性,用来存储当前点击的链接标识
        • visibility 是一个字符串
        • all active completed
      • 为链接添加点击事件,当点击导航链接的时候,改变
        • 在方法内写出选择判断,当点击某个值时,将选项匹配给visibility
        • 改变li遍历创建时的规则,由全部创建改为,filterTodos方法返回的数据
    <li 
      *ngFor="let todo of filterTodos; let i = index;"
      [ngClass]="{
        completed: todo.done,
        editing: currentEditing === todo
      }"
    >
    </li>
    
    public visibility: string = "all"
    ngOnInit(){
      // Angular初始化时,监听hash的变化
      // 此处要用箭头函数
      window.onhashchange = () => {
        // 当用户点击锚点时,我们需要获取当前的锚点链接
        // 然后动态的将根组件中的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 todos
      }else if(this.visibility === 'active'){
        return todos.filter(t => !t.done)
      }else if(this.visibility === 'completed'){
        return todos.filter(t => t.done)
      }
    }
    
    • 刷新保存过滤状态
      • 将以上代码中,哈希判断的代码作为另一个方法
      • 在钩子函数初始化时,执行一次哈希判断
      • 然后再在哈希事件中调用
      • 由于在哈希事件中,this指向window,因此,此时的this需要bind绑定
      ngOnInit(){
        // Angular初始化时,监听hash的变化
        // 此处要用箭头函数
        this.hashchangeHandler();
        window.onhashchange = this.hashchangeHandler.bind(this)
      }
      hashchangeHandler(){
        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
        }
      }
    
    • 数据改变触发的钩子函数

      • ngDoCheck()
      • 当数据发生变化时,刷新数据
    • 数据本地永久化存储

      • todos = JSON.parse(window.localStorage.getItem('todos') || '[]')
        • 将字符串转化为JSON数组
        • 从本地数据库window.localStorage读取数据
      • window.localStorage.setItem('todos', JSON.stringify(this.todos))
        • 将JSON数组转化为字符串
        • 将页面更新后的数据存储到本地数据库window.localStorage中
      public todos: {
        id: number,
        title: string,
        done: boolean
      }[] = JSON.parse(window.localStorage.getItem('todos') || '[]')
    
      ngDoCheck(){
        window.localStorage.setItem('todos', JSON.stringify(this.todos))
      }
    
  • 相关阅读:
    HDU5418.Victor and World(状压DP)
    POJ2686 Traveling by Stagecoach(状压DP)
    POJ3254Corn Fields(状压DP)
    HDU5407.CRB and Candies(数论)
    CodeForces 352D. Jeff and Furik
    CodeForces 352C. Jeff and Rounding(贪心)
    LightOj 1282 Leading and Trailing
    Ural 1057. Amount of Degrees(数位DP)
    HDU 2089 不要62 (数位DP)
    HDU5366 The mook jong (DP)
  • 原文地址:https://www.cnblogs.com/SharkJiao/p/13760848.html
Copyright © 2011-2022 走看看