• 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))
      }
    
  • 相关阅读:
    linux C/C++编程之库-动态库,静态库创建及使用
    类linux 系统iptables 系统初始化配置
    OS error set
    OpenWrt修改
    OpenWrt backfire trunk源码下载及编译
    OpenWrt compiles
    OpenWrt 学习网址
    nginx编译配置
    cocos2d-x中的坐标系
    SGU 231 Prime Sum 求&lt;=n内有多少对素数(a,b)使得a+b也为素数 规律题
  • 原文地址:https://www.cnblogs.com/SharkJiao/p/13760848.html
Copyright © 2020-2023  润新知