Angular

Angular

一、Angular简单介绍

  • ​ Google开发的的一款开源的web前端框架

  • ​ 基于TypeScript,与reactvue相比较它更适用于中大型企业级项目。

  • 学习路径

二、学习Angular必备基础

1. 必备基础

  • HTMLCSSJavaScript
  • Es6
  • Typescript

三、Angular环境搭建

1. 安装前准备工作

​ 1.1 安装前准备工作

  • ​ 安装node.js (稳定版本最好)

    • node.js是什么

      • node.js 是一个基于 Chrome V8 引擎的 JavaScirpt 运行环境。
    • 安装教程

      • 离线下载版1
      • 安装教程2
    • 问题

      • 无权限问题
      • 不是内部或外部命令,也不是可运行的程序
      • -4048ERROR
      • 环境变量问题
    • 终端中查看版本

      •   node -v
          npm -v 
        
  • ​ 安装cnpm

    • 终端中下载

      •   npm install -g cnpm --     registry=https://registry.npm.taobao.org
          
          cnpm -v
        
  • ​ 使用npm/cnpm命令安装 Angular/cli(只需安装一次)

    • 终端中下载

      •   npm install -g @angular/cli
               
          cnpm install -g @angular/cli
        

四、 软件设计原则与方法

(1) 原则

面试题: 可维护性,可修改性,可拓展性

  • YAGNI
  • You Arenot Gonna Need It,不写不需要的代码,写最重要的
  • DRY
    • Don’t Repeat Yourself,不要重复代码
  • OCP
    • Open Close Principle,开闭原则,开放拓展,封闭修改
  • LCHC
    • Low Coupling,High Cohesion,高聚合,低耦合原则,
  • 迪米特法则(最少知识法则)

( 2) 方法

1. MVVM框架的组成

​ 数据绑定,指令系统,组件式编程,路由和导航,

​ 状态保持,第三方组件库

2. Angular框架

五、 创建项目

  1. 打开命令行工具找到要创建项目的目录

  2. 创建项目

  3. ng new +项目名称

    • setTimeout is not defined错误
  4. ng serve --open运行项目

  5. 注意

    • 右键终端,以管理员模式打开

      •  ng v
         npm uninstall -g @angular/cli
         npm install -g @angular-cli
         cd angular
         ng new project1
         ng serve --open
        
      • 在过程中有不断地改变文件,目录的权限

      • ng new project1过程其实是npm i过程,不断给项目添加依赖,过程较慢,用ctrl+c中止,用cnpm install较快

        • 或者直接跳过npm过程:
        • ·ng new 项目名 --skip-install·
  6. 结果,成功运行

    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PXfrPiZk-1658480088036)(img/image-20220719150446550.png)]

六、 Angular开发工具介绍

(1)Webstorm

(2)Visual Studio Code

  • ​ 将所创建的Angular程序拖拽到VScode里

    • 加载扩展时出错,XHR failed 未解决问题
  • ​ 转为用离线安装.vsix插件的方式

    • 进入官网
    • VScode选项下搜索插件
    • 将下载的插件放在VScodebin目录
    • shift+鼠标右键选择在此处打开Powershell窗口
    • 输入 .\code --install-extension 插件名,successfully即成功

七、 目录结构分析

(1)e2e

  • ​ 端对端的测试点

(2)node——modules

  • ​ 项目中所需要的各种依赖
  • ​ 将package.json定义的模块通过npm/cnpm install下载到该目录下

(3)src (组件,app,module.ts定义模块)

  • ​ 作用

    • 写代码场所
    • 定义组件,定义服务场所
  • app

    • 存放组件,根模块

      • 根模块

        • app.module.ts根组件

        • app.component.html

        • app.component.scss

        • app.component.ts

  • assets静态资源文件

  • ​ browserlist

    • 支持该项目的浏览器列表
  • favicon.ico

    • 选择网页标题前的图标
  • index.html

    • HTML入口文件
  • main.ts

    • 整个项目的入口文件
  • polyfills.ts

    • 配置填充库可避免一些问题
    • 加载angular之前会首先加载该文件
  • styles.scss 全局的CSS文件

    • ng new project1选择的预编译方式作为后缀的文件
  • test.ts

    • 测试的入口文件

(4).editorconfig

  • ​ 一个编辑器配置文件

(5)package.json

  • ​ 一个项目配置文件
    • 定义项目的名称,版本,项目所需的各种依赖

(6)README.md

  • ​ 说明如何运行,编译项目

​ 其他的基本上是配置文件

八、 使用Angular

(1)在Angular中如何创建组件

  • 创建组件/服务 :

    •   ng g
      
  • http://cli.angular.io/

    • 创建组件

      •  ng g component components/news
        
    • 使用组件

      • 先将该组件引入到app.modules.ts
        • 当用命令时,自动引入
          • import { NewsComponent } from './components/news/news.component';
          • NewsComponent
          • 当没有直接引入时,手动添加
            • 以APP为当前目录
        • 在其他组件里用该组件,直接输入名称
          • 当作标签使用,拓展html标签
          • <组件名称>
          • 中间夹内容好像无显示
          • 当只改变改变一个组件时,ctrl+s就可直接刷新页面
          • 添加新组件时,就得ng serve --open

(2)在Angular中如何实现数据?

  • 在.ts文件中public定义数据 (默认也是public)

    •  public title="我是前端"
       msg="我是msg"
       username:string='张三'
       number:any=123456
        
        //推荐使用
        public student:string='王麻子'
      
  • 在.html文件中绑定数据

    •  <h1>{{title}}h1>
       <h2>{{msg}}h2>
      
  • 声明属性的几种方式

    • public(公有,默认)
      • 可在当前类,也可在类外使用
    • protected(保护)
      • 只在当前类和子类里能访问
    • private(私有)
      • 只在当前类能访问该属性
  • 声明对象

    • .ts文件中定义
      • public userinfo:object={,,}
    • .html文件中绑定
      • error TS2339: Property 'age' does not exist on type 'object'问题
        • 改为public userinfo:any={,,}
    • 或者在.ts文件中定义属性,但是不赋值,在构造函数里赋值
      • this.msg='' ;
    • 或已经赋值,但可以在构造函数中改变值
      • 获取值
        • console.log(this.msg)
      • 重新赋值
        • this.msg="改变值"

(3)如何在Angular模板里绑定数据

  • 静态属性

    •  <div title="我是一个div">
           鼠标瞄上去会显示“我是一个div”
       div>
      
  • 动态属性

    •  
       <div [title]="student">
             李华(鼠标瞄上去会显示“这是一个学生”)
       div>
      

(4)如何在Angular里绑定HTML

  •  <div>{{content}}div>
     <div>解析前-->解析后div>
     <span [innerHTML]="content" class="red">span>
    

(5)在Angular中简单运算

  •   1+2={{1+2}}
    

(6)在Angular中数据循环

  • 简单数组

    • in .ts
      public arr=['1','2','3']
      in .html
      <ul>
          <li *ngFor="let item of arr">
             {{item}}
          li>   
      ul>
      
  • Property ‘item’ does not exist on type ‘HomeComponent’.问题未解决

  • 对象数组

    •  in .ts
       public userlist:any[]=[{
          name:'zara',
          time:1
         },{
          name:'marry',
          time:4
         }];
        in .html
         

      复杂数组

      • {{item.name}}--{{item.time}}
      • 为什么这个复杂的可以输出
  • 嵌套数组

    •  in .ts
       public car:any[]=[{
          p:'宝马',
          list:[{
            price:100,
            n:'w'
          }]},{
          p:'奥迪',
          list:[{
            price:200,
            n:'a'
          }]
         }]
        in .html
        <ul>
          <li *ngFor="let m of car">
              <h2>{{m.p}}h2>
              <ol>
                  <li *ngFor="let i of m.list">
                      {{i.price}}--{{i.n}}
                  li>
              ol>
          li>
          为什么可以得到嵌套数据
        ul>
       
      

(7)在Angular中引入图片

  • 引入本地图片

    • 属于静态资源,存入assets

    • 在src中存放路径

      • <img src="assets/picture/1.png" alt="我的图片">
        
  • 引入网上图片

    • 复制图片地址
    • 定义图片数据
    • 渲染到html中,给属性赋值,需加 [ ]

(8)在Angular数组循环中显示数据索引

  • 定义数组

  • 在循环中加入 let key=idex

    • <h1>循环数据 显示数据索引索引h1>
      <ul>
          <li *ngFor="let item of piclist;let key=index ">
              {{key}}---->{{item.title}}
          li>
      ul>
      

(9) 条件判断 *ngif

  • <ul>
        <li *ngFor="let item of piclist;let key=index ">
            <span *ngIf="key==1" class="red">{{key}}---->{{item.title}}span>
            <span *ngIf="key!=1">{{key}}---->{{item.title}}span>
        li>
    	ul>
    

(10) 开关语句 *ngSwitch

  •  <h1>开关*ngSwitchh1>
    <div [ngSwitch]="num">
        <div *ngSwitchCase="1">正确输入div>
        <div *ngSwitchCase="2">重新输入div>
        <div *ngSwitchDefault>错误输入div>
    div>
    
    

(11) 动态改变class—*ngClass

  • <div [ngClass]="{'orange': flag,'blue':!flag}">
      动态变化class
    div>
    

(12) --ngStyle

  •   <p [ngStyle]="{'color':'blue' }">ngStyle,固定值+单引号p>
      
    

(13) --管道

  • Angular内置方法

    • http://bbs.itying.com/topic/5bf519657e9f5911d4f2a34

    • 日期格式化

      •  <h1>管道时间格式化,注意+单引号h1>
         {{today | date: 'YYYY-MM-dd HH:mm:ss'}}
        
  • 自定义方法

(14) 执行事件 (click)=“getData()”

  • 在.HTML中显示效果

    •  <h1>事件h1>
       {{num}}
       <button (click)="run()">执行事件button>
       <button (click)="getData()">获取数据button>
       <button (click)="setData()">改变数据button>
      
  • 在 .ts中写执行方法

    •  run(){
           alert("执行事件");
        }
        
        getData(){
          alert(this.flag);
        }
        
        setData(){
           this.num='改变后数据';
        }
      

(15) 表单事件 事件对象

  • 通过事件对象监听文本输入,得到文本响应次数,文本数据…

    •  <button (click)="runevent($e)">监听button>
       <h1>表单事件 事件对象h1>
       keydown
       <input type="text" (keydown)="keyDown1()">
       
       keyup
       <input type="text" (keyup)="keyUp1()">
        
       keyDown1(){
          console.log('keyDown');
        }
        
        // keyDown2(){
        //   if(e.keycode==1)
        //   {
        //     console.log('按下了回车')
        //   }
        //   else{
        //     console.log(e.keycode);
        //   }
        // }
        
        keyUp1(){
          console.log('keyUp');
        }
        
        runevent(e)){
           var dom:any=e.target;
           dom.style.color="red";
        }
      
      • 问题无法监听到具体内容,事件e显示未定义

(16) 双向数据绑定–MVVM(仅针对表单)

  • Model <—> View

  • Model改变会改变视图,反之亦然

  • 先在 app.module.ts中引入FormsModule

    •   import { FormsModule } from '@angular/forms';
        在ngmodules添加
      
    • 同时改变

      •  <h1>双向数据绑定---MVVM(仅针对表单)h1>
        <input type="text" [(ngModel)]='keywords'> {{keywords}}
        <button (click)="change()">改变keywords值button>
        <div *ngIf="keywords=='1'">直接改变了,还需要监听吗div>
        

九、实现预约功能

  • 当前组件的样式写在当前的css文件中

  • 全局的样式,写在根组件app.component.css

  • 首先先在.ts文件定义一个对象

  • 将预约功能中的每部分都纳入该对象中

    • public peopleinfo:any={
          userage:'',
          sex: '1',
          citylist:['上海','北京','广东'],
          city:'北京',
          hobby:[{title:'吃饭',checked:false},{title:'睡觉',checked:true},{title:'打豆豆',checked:true}],
          mark:''
        }
      

(1) 文本框–text

  • jQuery方式

  •  <li>姓 名: <input type="text" id="username">li>
     
      let  usernameDom:any=document.getElementById('username');
        console.log(usernameDom.value)
    
  • 双向数据绑定方式

  •  <li>年 龄: <input type="text"  [(ngModel)]="peopleinfo.userage">li>
    
  • 可直接打印数据

(2)复选框–radio

  • 双向绑定数据方式

    •  <li>性 别:
       <input type="radio" value="1" name="sex" id="sex1"    [(ngModel)]="peopleinfo.sex"> <label for="sex1">label>
       <input type="radio" value="2" name="sex" id="sex2"  [(ngModel)]="peopleinfo.sex"> <label for="sex2">label>
      

(3)下拉框–select option

  • 双向绑定数据方式

    •  <li>城 市:
        <select name="city" id="city"      
         [(ngModel)]="peopleinfo.city">
        <option [value]="item" *ngFor="let item of  
          peopleinfo.citylist">{{item}}option>select> 
       li>
        
      

(4)多选框–checkbox

  • 双向绑定数据方式

    •  <li>爱 好:
       <span *ngFor="let item of peopleinfo.hobby; let  
                     key=index;">
       <input type="checkbox" [id]="'check'+key" 
              [(ngModel)]="item.checked"><label        
              [for]="'check'+key">{{item.title}}label>            &nbs 
       p;
       span>li>
        
      

(5)文本域–textarea

  • 双向绑定数据方式

    •  <li>备 注:
       <textarea name="mark" id="mark" cols="30" rows="10" 
                 [(ngModel)]="peopleinfo.mark">textarea>
       li>
      

(6)获取信息

  <button (click)="doSubmit()">获取信息button>

(7)数据管道预处理

  <pre>
        {{peopleinfo | json}}
  pre>

(8)结果展示

十、 toDoList搜索缓存功能

(1)效果展示

十一、Angular服务,实现toDoList数据持久化

(1)Angular中的服务

  • 组件中的方法无法彼此调用
  • 公共的方法存在服务(service)中,可被其他组件共享调用
  • 服务和服务之间可以相互调用

(2) 创建服务

  • 命令

  •  ng g service my-new-service
     创建到指定目录下
     ng g service services/storage
    
  • 引入到app.module.ts中,并配置服务

    • 引入服务路径

      import { StorageService } from './services/storage.service';
      
    • 加入服务配置

      •  providers: [StorageService], //配置项目所需要的服务
        
  • 增加服务类型

  • 当其他组件要使用服务,同样引入

    • 更新路径

      •   import { StorageService } from '../../services/storage.service';
          
        
    • 实例化(初始化对象)

      • 方法一(不推荐)

            var storage=new StorageService();
            console.log(storage);
        
      • 方法二(推荐)

           //在构造函数中初始化
           constructor(public todo:StorageService)
          {  }
        
          ngOnInit(): void {
            console.log('页面刷新会触发这个生命周期函数!');
        
          var todolist=this.todo.get('todolist');
            if(todolist)
            {
              this.todolist=todolist;
            }
          }
        
        • 注意:每刷新一次界面便会触发生命周期函数
    • 使用

      • 将实例化的对象作为组件的属性进行使用,并调用方法

        • this.todo.set('todolist',this.todolist);
          
    • 长期存储函数

      • set(key:any,value:any){
        localStorage.setItem(key,JSON.stringify(value));
          }
        
      • 界面-->检查-->应用-->存储-->本地存储空间查看

    • 返回存取内容函数

      •  get(key:any){
            return JSON.parse(localStorage.getItem(key)||'0');
           //return JSON.parse(localStorage.getItem(key)||'{}');
         }
        
    • 在存储空间中删除函数

      • remove(key:any)
          {
            localStorage.removeItem(key);
          }
        
  • 最终界面(刷新后仍保持)

十二、 DOM操作,@ViewChild,Angular执行css3动画

(1) Angular中的DOM操作(原生JS)

  • 生命周期函数ngOnInit只是组件和指令初始化完成,并不是真正的dom加载 完成

  •     ngOnInit(): void {
        //组件和指令初始化完成,并不是真正的dom加载完成
        let      
        oBox:any=document.getElementById("DOM");
        console.log(oBox.innerHTML);
        oBox.style.color="red";}
        
        <div id="DOM">
        这是DOM组件
        </div>
    

(2)另一个生命周期函数ngAfterViewInit()

  • div 里 多了ngif类操作

  • 视图加载完后触发的方法,dom加载完毕(建议)

    •      ngAfterViewInit():void{
          let          
          oBox1:any=document.getElementById("DOM1");
          console.log(oBox1.innerHTML);
          oBox1.style.color="blue";}
          
          <div id="DOM1" *ngIf="flag">
          这是DOM组件这是
          </div>
      

(3) Angular中的DOM操作(ViewChild)

  • 功能一: 实现DOM操作

    • 先起名 #name

        <div #dom3>
          这是ViewChild方法
        div>
      
    • 业务逻辑中定义

        @ViewChild('dom3') mybox:any;
      
    • 另一个生命周期函数中使用

        ngAfterViewInit():void{
            //@ViewChild
           console.log(this.mybox.nativeElement);
           this.mybox.nativeElement.style.width='200px';
           this.mybox.nativeElement.style.height='30px';
           this.mybox.nativeElement.style.background='yellow';
           console.log(this.mybox.nativeElement.innerHTML);
        }
      
  • 功能二: 父子组件中通过ViewChild调用子组件的方法

    • 在父组件.HTML中引用子组件,并为子组件取名 # name

    •   <app-news #child>app-news>
      
    • 将子组件通过ViewChild赋给父组件的一个属性

    •    @ViewChild('child') child:any;
      
    • 通过该属性调用子组件的方法

      •   runClick(){
             this.child.runNews();
          }
        

(4) CSS3的动画效果

  • 实现侧边栏

    •  <aside id="aside">
          这是一个侧边栏
      aside>
      
  • 显示侧边栏效果(使用原生JS获取dom)

    •   showAside(){
          //原生JS获得dom节点
        let asidedom:any=document.getElementById("aside");
          asidedom.style.transform="translate(0,0)";
        }
      
  • 设置效果

    •  class='name'  --> .name{}
       id='name' --> #name{}
       li --> li{}
      

十三、 Angular父子组件以及组件之间通讯

(1)父组件给子组件传值 @input

  • 子组件可以获取父组件的数据

    • 父组件调用子组件时传入数据

      •  <app-child [title]="title" [msg]="msg" [run]="run" [header]="this">app-child>
        
    • 子组件引入Input模块

       import { Component, OnInit ,Input} from '@angular/core';
      
    • 子组件@input接受父组件传来的数据

      • //input装饰器
          @Input() title:any; //接收父组件传来的数据
          @Input() msg:any; //接收父组件传来的数据
          @Input() run:any; //接收父组件传来的数据
          @Input() header:any; //接收父组件传来的数据/
        
  • 子组件可以获得父组件的方法和对象

    • 同上

(2)子组件给父组件传值

  • @ViewChild主动获取子组件的数据和方法(推荐)

      • 在父组件.HTML中引用子组件,并为子组件取名 # name

        •   <app-news #child>app-news>
          
      • 将子组件通过ViewChild赋给父组件的一个属性

      •    @ViewChild('child') child:any;
        
      • 通过该属性调用子组件的方法

        •   runClick(){
               this.child.runNews();
            }
          
  • @Output触发父组件的方法

    • 父组件可以获取子组件的数据

      • 子组件引入OutputEventEmitter(事件驱动)

        •  import { Component, OnInit ,Input,Output,EventEmitter} from '@angular/core';
            
          
      • 子组件中实例化EventEmitter

        • @Output() outer=new EventEmitter();
          
      • 子组件通过EventEmitter对象outer实例广播数据

        •  sendParent(){
              alert('11');
              this.outer.emit('我是子组件的数据');
            }
          
      • 父组件调用子组件时,定义接收事件,outer就是子组件的EventEmitter对象outer

        •  <app-child #child (outer)="runAlart($event)"></app-child>
          
      • 父组件接收到数据会调用自己的runParent()方法,这个时候就能拿到子组件的数据

        • runAlart(e:any){
              console.log(e);
              alert('我是父组件的runAlart()方法');
            }
          
    • 父组件可以获取子组件的方法

      • 同上

(3)非父子组件

  • 组件之间传值localstorage
  • 共享方法服务service

十四、Angular中的生命周期函数

  • 组件的生命周期函数
    • 组件创建,组件更新,组件销毁时会触发的一系列方法

    • 当Angular使用构造函数新建一个组件或指令后,就会按照以下顺序在特定时刻调用这些生命周期钩子方法

      • 钩子方法 用途及时机
        constructor() 构造函数中除了使用简单的值对局部变量进行初始化之外,什么都不应该做(非生命周期函数)
        ngOnChanges() 当Angular(重新)设置数据绑定输入属性时响应,该方法接受当前和上一属性值的SimpleChanges对象,当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在ngOnInit()之前
        ngOnInit() 在Angular第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。在第一轮ngOnChanges()完成之后调用,只调用一次。使用ngOnInit()两个原因:1.在构造函数之后马上执行复杂的初始化逻辑;2.在Angular设置完输入属性之后,对该组件进行
        ngAfterViewInit() 初始化完组件视图及其子视图之后调用,第一次ngAfterContentChecked()之后使用
        ngOnDestroy() 当Angular每次销毁指令/组件之前调用并清扫,在这里反订阅可观察对象和分离事件处理器,以防内存泄漏。在Angular销毁指令/组件之前调用。

十五、 Rxjs异步数据流编程

(1)Rxjs介绍

  • RxJS是Reactive编程理念的JavaScript版本,Rx是一种针对异步数据流的编程,响应式编程,它将一切数据,包括HTTP请求,DOM事件或者其他普通数据包等包装成流的形式,然后用强大丰富的操作符对流进行处理,使能以同步编程的方式处理异步数据,并组合不同的操作符来轻松优雅的实现你所需要的功能。

  • Angular引入RxJS是为了让异步可控,更简单

  • RxJS提供很多模块,常用的是Observable,fromEvent

  • 常见异步编程的几种方法

    • 回调函数

      • 服务

      //回调函数 Callback()
      getCallbackData(cb:any){
      setTimeout(()=>{
      var data=‘张三–CallBack()’;
      // return data;
      cb(data);
      },1000)
      }

      
      - 组件
      
      ```typescript
      //异步方法--回调函数
        this.search.getCallbackData((b:any)=>{
            console.log(b);
        });
      
    • 事件监听、发布订阅

    • Promise (es6)

      • 服务

         //Promise()
        getPromiseData(){
        
         return new Promise((resolve)=>{
        
          setTimeout(()=>{
            var data='张三--Promise()';
            resolve(data);
           },1000);
         })
        }
        
      • 组件

         //异步方法--Promise()
          var promiseData=this.search.getPromiseData();
          promiseData.then((c)=>{
            console.log(c);
          })
      
    • RxJS

      • 引入Observable

        • import { Observable} from 'rxjs';
          
      • 服务

        •  //RxJS获取异步方法里的数据
            getRxjsData(){
            
              return new Observable((observer)=>{
                
                 //定时器
                setTimeout(() => {
                  var data='张三--RxJS()';
                  observer.next(data);
                  // observer.error('数据');
            
                }, 2000);
              })
            }
          
      • 组件

        •  //异步方法--RxJS()
              var rxjsData=this.search.getRxjsData();
              rxjsData.subscribe((d)=>{
                  console.log(d);
              })
          

(2)Promise和RxJS异步处理比较

  • RxJS 比 Promise 强大
    • 可中途撤回
    • 可发射多个值
    • 提供多种工具函数

(3)Rxjs unsubscribe取消订阅

  • Promise创建后,动作无法撤回,Observable的动作可以通过unsubscribe方法中途撤回,且在内部做了智能的处理。

  • //异步方法--RxJS(),动作撤回,组件
        var stream=this.search.getRxjsData();
        var data=stream.subscribe((d)=>{
            console.log(d);
        })
         setTimeout(() => {
          data.unsubscribe(); //取消订阅
        }, 1000);
    

(4)Rxjs 订阅后多次执行

  • Promise最终结果要么reclose(兑现),要么reject(拒绝),且只能触发一次,若在同一个Promise对象上多次调用resolve方法,就会抛出异常。

  • observable可以不断触发下一个值,next();(爬虫)

  • 服务

    •   //Rxjs 多次执行
        getRxjsIntervalData(){
           let count =0;
           return new Observable<any>((observer)=>{
        
               setInterval(()=>{
                   count++;
                   var username='张三--Rxjs--Interval'+count;
                   observer.next(username);
               },1000)
           })
        }
        
      
  • 组件

    •   //7. rxjs执行多次
          var streamInterval=this.search.getRxjsIntervalData();
          streamInterval.subscribe((f)=>{
              console.log(f);
          })
      

(5)Angular6.x之前使用Rxjs的工具函数map(处理) ,filter(过滤)

  • filter+pipe
//8.pipe,filter
    var streamInterval1=this.search.getRxjsIntervalData();
    streamInterval1.pipe(
      filter((value:any):any=>{
          if(value%2==0)
              return true;
      })
    ).subscribe((f)=>{
        console.log(f);
    })
 
  • map+pipe
 //9.map()
    var streamInterval2=this.search.getRxjsIntervalData();
    streamInterval2.pipe(
      map((value:any):any=>{
          if(value%2==0)
              return value*value;
      })
    ).subscribe((f)=>{
        console.log(f);
    })
  • pipe-filter-map
 //10. pipe,filter,map,连续先过滤再处理数据
    var streamInterval1=this.search.getRxjsIntervalData();
    streamInterval1.pipe(
      filter((value:any):any=>{
          if(value%2==0)
              return true;
      }),
      map((value:any):any=>{
        if(value%10==0)
            return value*value;
      })
    ).subscribe((f)=>{
        console.log(f);
    })

(6)Angular6.x以后Rxjs的变化以及使用

  • RSJS6改变了包的结构,主要变化在import方式和operator上面以及使用pipe()

  •  import { filter, map } from 'rxjs';
    

十六、Angular中的数据交互(get,jsonp,post)–服务器

  • Angular5.x之后get,post,Jsonp和服务器交互使用的是HttpClientModule模块。

(1)Angular get 请求数据

  • app.modiles.ts中引入HttpClientModule并注入

    •  import { HttpClientModule } from '@angular/common/http';
      
    •   imports: [   //配置当前模块运行依赖的其他模块   
            BrowserModule,FormsModule,HttpClientModule
        ],
      
  • 在用到的地方引入HttpClient并在构造函数中声明

    •  constructor(public http:HttpClient) { }
      
  • get请求数据

    •  getData(){
          // alert('get请求数据');
          //服务器必须跨域
          let api="http://a.itying.com/api/productlist";
        
          this.http.get(api).subscribe((response:any)=>{
        
              console.log(response);
              this.list=response.result;
          })
        }
      

(2)Angular post 提交数据

  • app.modiles.ts中引入HttpClientModule并注入

    • import { HttpClientModule } from '@angular/common/http';
      
    • imports: [   //配置当前模块运行依赖的其他模块   
            BrowserModule,FormsModule,HttpClientModule
        ],
      
  • 在用到的地方引入HttpClient,HttpHeaders并在构造函数中声明HttpClient,需设置请求头

    •  //当作一个服务
      import { HttpClient,HttpHeaders } from '@angular/common/http';
      
    •  constructor(public http:HttpClient) { }
      
  • post请求数据

    •  dologin(){
          // alert('sub');
          //手动设置请求的类型
          const httpOption={headers:new HttpHeaders({'Content-Type':'application/json'})}
            
          //存在跨域
          let api='http://127.0.0.1:3000/dologin';
          this.http.post(api,{"username":"张三","age":"20"},httpOption).subscribe((reply)=>{
          console.log(reply);
              
          });
        }
      

(3)Angular Jsonp 请求数据

  • app.modiles.ts中引入HttpClientModule,HttpClientJsonpModule并注入

    • //引入数据交互模块
      import { HttpClientModule,HttpClientJsonpModule } from '@angular/common/http';
      
    •  imports: [   //配置当前模块运行依赖的其他模块
          BrowserModule,FormsModule,HttpClientModule,
          HttpClientJsonpModule
        ],
      
  • 在用到的地方引入HttpClient,并在构造函数中声明HttpClient

    •   constructor(public http:HttpClient) { }
      
  • Jsonp请求数据

    •  getJsonpData(){
          // alert('Jsonp');
          //网络-右键-在新的标签页打开
          let api="http://a.itying.com/api/productlist";
          this.http.jsonp(api,'callback').subscribe((response)=>{
              console.log(response);
          })
        }
      

(4)Angular中使用第三方模块axios请求数据

  • 安装axios

    •  cnpm installl axios --save
       ng serve --open
      
  • 在用到的地方引入axios

    • 创建服务和方法

        ng g service services/httpservice
        //用promise封装异步,也可用rxjs
        axiosGet(api:any){
          
            //用promise封装异步,也可用rxjs
            return new Promise((resolve:any,reject:any)=>{
              axios.get(api)
                .then(function(response:any){
                //handle success
                // console.log(response);
                 resolve(response);
                 })
               .catch(function (error:any){
                //handle error
                console.log(error);
              })
            })}
      
    • 引入服务,并配置app.module.ts

      •  import { HttpserviceService } from './services/httpservice.service';
         
         providers: [StorageService,HttpserviceService], //配置项目所需要的服务
        
    • 在使用服务的.ts文件中引入服务

      • //使用服务里的axios获取数据
        import { HttpserviceService } from '../../services/httpservice.service';
        
      • 在构造函数中定义对象并初始化

      constructor(public http:HttpClient,public httpservice:HttpserviceService ) { }

      
      
    • 使用方法

      • getAxiosData(){
            let api="http://a.itying.com/api/productlist";
            this.httpservice.axiosGet(api).then((data)=>{
              console.log(data);
            })
          }
        
  • 看文档使用

十七、 Angular中的路由

  • 路由就是根据不用的url地址动态地让根组件挂在其他组件来实现按一个单页面应用

(1)Angular创建一个默认带路由的项目

  • 命令创建项目

    •  ng new Route --skip-install
       -y
       -scss
       //转到项目里
       cd Route
       //建立依赖
       cnpm install
      
      • 比未选择路由时,app多了个配置路由的app-routing-modules.ts文件,app.module.ts也多了引入模块
  • 创建需要的组件

    •   ng g component components/product
        ng g component components/news
        ng g component components/home
      
  • app-routing-modules.ts引入组件,并配置路由

    •  //引入挂载模块
      import { NewsComponent } from './components/news/news.component';
      import { HomeComponent } from './components/home/home.component';
      import { ProductComponent } from './components/product/product.component';
      
      //配置路由
      const routes: Routes = [
         { path:'home',component:HomeComponent},
         { path:'news',component:NewsComponent},
         { path:'product',component:ProductComponent}
      ];
      
  • 更改url,访问挂载的不同组件,其放在(手动更改配置)

    • //可决定位置 
      <router-outlet></router-outlet>
      
    •  //根组件网址
       http://localhost:4200/
       //挂载的网址url
       http://localhost:4200/home
       http://localhost:4200/news
       http://localhost:4200/product
      
  • 改为通过点击实现跳转界面

    • 找到app.component.html根组件模块,配置router-outlet显示动态加载的路由 (.html)

       <a [routerLink]="['/home']">首页</a>
      
       <a routerLink='/news'>新闻</a>
      
       <a routerLink='/product'>商品</a>
      
    • 比传统方式响应快些

(2)默认路由路径配置

  • 在路由文件中增加匹配不到路由时,默认跳转到的界面

    •   //配置路由
      const routes: Routes = [
         { path:'home',component:HomeComponent},
         { path:'news',component:NewsComponent},
         { path:'product',component:ProductComponent},
      
         //匹配不到路由时,默认挂载的组件
         {path:'**',redirectTo:'news'}
      ];
      

(3)routerLinkActive设置routerLink默认选择路由

  • 可设置选中后的样式

    •      <a [routerLink]="['/home']" routerLinkActive="router-link-active">首页</a>
        
          <a routerLink='/news' routerLinkActive="router-link-active">新闻</a>
        
          <a routerLink='/product' routerLinkActive="router-link-active">商品</a>
        
      

(4)动态路由

1. get传值
  • ​ 跳转

    •   <ul>
         <li *ngFor="let item of list;let key=index">
             <a [routerLink]="['/news-content']" [queryParams]="{aid:key}">
                 {{key}}---{{item}}
             </a>
         </li>
      </ul>
      
  • 接收

  •   import { ActivatedRoute } from '@angular/router';
     constructor(public route:ActivatedRoute) { }
       ngOnInit(): void {
      console.log(this.route);
      
    this.route.queryParams.subscribe((data)=>{
         console.log(data);
      })
    } 
    
2. 动态路由
  • 配置动态路由

    •   //配置路由
      const routes: Routes = [
         { path:'home',component:HomeComponent},
         { path:'news',component:NewsComponent},
         { path:'product',component:ProductComponent},
         { path:'newscontent/:aid',component:NewscontentComponent},
         //匹配不到路由时,默认挂载的组件
         {path:'**',redirectTo:'home'}
      ];
      
  • 跳转

    •   <h2>动态路由h2>
        <ul>
          <li *ngFor="let item of list;let key=index">
              <a [routerLink]="['/newscontent/',key]">
                  {{key}}--{{item}}
              a>
          li>
        ul>
      
  • 接收

    •   //动态路由获取url的传值
          this.route.params.subscribe((data)=>{
              console.log(data);
          })      
      

(5)动态路由的js跳转(业务逻辑判断)

  • 引入

    •  import { Router } from '@angular/router';
      
  • 初始化,声明

    •  constructor(public router:Router) { }
      
  • 跳转

    •  getProductContent(){
        // alert('js');
          //路由跳转, 动态路由
          this.router.navigate(['/productcontent/','134']);
        }
      
         //路由跳转, 普通路由
        ToHome(){
          this.router.navigate(['/home/']);
        }
      

(6)路由get传值js跳转

  • 引入NavigationExtras

    import { Router ,NavigationExtras } from ‘@angular/router’;

    
    
  • 定义一个goNews方法执行跳转,用NavigationExtras配置传参并跳转

    •   //get传值
        goNews(){
           //跳转并进行get传值
           //传参
           let queryParams:NavigationExtras={
            queryParams:{'aid':123}
           }
       this.router.navigate(['/news'],queryParams);
        }
      

(7)父子路由(嵌套路由)

  • 应用场景

  • 创建组件引入组件

    • 直接在父组件目录下创建,更加直白

      •   ng g component components/home/welcome
        
    • 引入,app.module.ts自动引入,在app-routing.module.ts

      •   //子组件
        import { WelcomeComponent } from './components/home/welcome/welcome.component';
        import { SettingComponent } from './components/home/setting/setting.component';
        import { PcateComponent } from './components/child/pcate/pcate.component';
        import { PlistComponent } from './components/child/plist/plist.component';
        
  • 配置路由

    • 直接在父路由配置下嵌套配置,可设置默认

      •   //配置路由
        const routes: Routes = [
           { 
             path:'home',component:HomeComponent,
             children:[
               { path:'welcome',component:WelcomeComponent},
               { path:'setting',component:SettingComponent},
        
               //可以再叠加使用默认
               { path:'**',redirectTo:'welcome'}
             ]
           }]
        
    • 注意:还需要在父组件.html文件下添加,使得匹配到的子路由组件能够挂载在父路由上

      •   <router-outlet>
          router-outlet>
        

十八、Angular无人点餐无人收银系统

(1)创建项目

  • 管理员身份打开命令提示符

  •   D:
      cd angular #切换到存入目录
      ng new case --skip-install #创建项目
      route --y   #选择路由
      css/scss... #任选
      cd case  #切换到项目里
      cnpm install #安装依赖
    
  • 将项目拖拽到VS code中,在VS code终端操作

    •  ng serve --open  #试运行
      
  • 创建组件(数量按需要定)

    •    ng g component components/home  #组件
          ng g component components/conduct  #组件
      
  • 将组件引入路由,并配置

    •  //引入
      import { HomeComponent } from './components/home/home.component';
      import { ProductComponent } from './components/product/product.component';
      
      //配置路由
      const routes: Routes = [
        { path:'home',component:HomeComponent},
        { path:'product',component:ProductComponent},
        //默认路由
        { path:'**',redirectTo:'home'}
      ];
      
  • 在创建项目时,选择路由即体现在app.component.html中会出现

    •   <router-outlet>router-outlet>
        
      

ting.component’;
import { PcateComponent } from ‘./components/child/pcate/pcate.component’;
import { PlistComponent } from ‘./components/child/plist/plist.component’;
```

  • 配置路由

    • 直接在父路由配置下嵌套配置,可设置默认

      •   //配置路由
        const routes: Routes = [
           { 
             path:'home',component:HomeComponent,
             children:[
               { path:'welcome',component:WelcomeComponent},
               { path:'setting',component:SettingComponent},
        
               //可以再叠加使用默认
               { path:'**',redirectTo:'welcome'}
             ]
           }]
        
    • 注意:还需要在父组件.html文件下添加,使得匹配到的子路由组件能够挂载在父路由上

      •   <router-outlet>
          router-outlet>
        

十八、Angular无人点餐无人收银系统

(1)创建项目

  • 管理员身份打开命令提示符

  •   D:
      cd angular #切换到存入目录
      ng new case --skip-install #创建项目
      route --y   #选择路由
      css/scss... #任选
      cd case  #切换到项目里
      cnpm install #安装依赖
    
  • 将项目拖拽到VS code中,在VS code终端操作

    •  ng serve --open  #试运行
      
  • 创建组件(数量按需要定)

    •    ng g component components/home  #组件
          ng g component components/conduct  #组件
      
  • 将组件引入路由,并配置

    •  //引入
      import { HomeComponent } from './components/home/home.component';
      import { ProductComponent } from './components/product/product.component';
      
      //配置路由
      const routes: Routes = [
        { path:'home',component:HomeComponent},
        { path:'product',component:ProductComponent},
        //默认路由
        { path:'**',redirectTo:'home'}
      ];
      
  • 在创建项目时,选择路由即体现在app.component.html中会出现

    •   <router-outlet>router-outlet>
        
      
  • 没数据,暂时不继续!

你可能感兴趣的:(前端,angular.js,javascript,前端)