前言

  1. 本文档假设你已经熟悉了 HTMLCSS,[JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript) 和来自 [最新标准](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Language_Resources) 的一些知识,比如 [类](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes) 和 [模块](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)。 下列代码范例都是用最新版本的 [TypeScript](https://www.typescriptlang.org/) 写的。 大多数 Angular 代码都只能用最新的 JavaScript 编写,它会用 [类型](https://www.typescriptlang.org/docs/handbook/classes.html) 实现依赖注入,还会用[装饰器](https://www.typescriptlang.org/docs/handbook/decorators.html)来提供元数据。<br /> Angular 是一个用 HTML 和 TypeScript 构建客户端应用的平台与框架。 Angular 本身就是用 TypeScript 写成的。它将核心功能和可选功能作为一组 TypeScript 库进行实现,你可以把它们导入你的应用中.<br /> 涵盖了组件、模板语法、路由、服务以及通过 HTTP 访问数据等,但是格式更简单,且遵循了绝大部分最佳践。<br />

开启hello world

//创建一个项目(用powerShell创建)
   ng new xxx
//启动项目 (终端)
   ng serve

打开文件项目
删除.html 所有代码 只剩hello world 开启服务

一、基本入门

基础知识

1-1 双向绑定 ngModel

注册

import {FormsModule} from '@angular/forms';
 imports: [
    BrowserModule,
    FormsModule,    
  ],

1-2 (change)

<input type="text" 
 (change)="handleChange($event)"/>
 {{msg}}
 handleChange(){
    console.log(this.checked)
  }

1-3 (ngModelChange)

[(ngModel)]="checked"
 (ngModelChange)="handleChange($event)"/>
export class HeaderComponent implements OnInit {
public msg:string = "hello world";
public checked:boolean = true;
...
  handleChange(){
    console.log(this.checked)
  }

1-4 获取DOM / 生命周期获取DOM

第一种:

  ngOnInit() {
    var app:any = document.getElementById("app");
    app.style.color="red"
    console.log(app)
  }

第二种 生命周期获取dom

<div id = "show" *ngIf="flag">显示</div>
-----------------------------------------------------------
//about.component.ts
  public flag:boolean = true;                               //定义ngIf(flag)
  constructor() { }

  ngOnInit() {
    // 指令和组件初始化
    var app:any = document.getElementById("app");
    app.style.color="red"
    // console.log(app)
    // var show:any = document.getElementById("show");   //
    // console.log(show);                                 //第一种方法:打印为空
  }
  ngAfterViewInit(){
    // 推荐在此生命周期中 操作Dom
    var show:any = document.getElementById("show");
    console.log(show);                                     //第二种方法:打印
  }

1-5 viewChild 装饰器

<div #app *ngIf="flag">显示</div>
     ----                                        /////1.给dom 命名
import { Component, OnInit, ViewChild} from '@angular/core';1. //////配置ViewChild
                            -----------
@Component({
  selector: 'app-about',
  templateUrl: './about.component.html',
  styleUrls: ['./about.component.css']
})
export class AboutComponent implements OnInit {
public flag:boolean = true;
@ViewChild('app',{static:false}) app:any;           //////2.
  constructor() { }

  ngOnInit() {

  }
  ngAfterViewInit(){                                ///////3.
   console.log(this.app);
  }
}

2、指令ngFor,ngIf …

//.html

<div *ngFor="let item of arr">{{item.name}}</div>
<div *ngIf="isShow">你好</div>

//header.component.ts

export class HeaderComponent implements OnInit {
  public arr:object[] = [{name:"html",age:12},{name:'css',age:23}];
  public isShow:boolean=true;
 // public imageUrl:string="https://dss0.baidu.com/73t1bjeh1BF3odCf/it/u=3093620924,1794231155&fm=85&s=BA917F81683046017AA9ADCC0300C023"
 //public msg:string = "我喜欢写代码"
  constructor() { }
...
}

3、属性绑定[src]

<img [src]="imageUrl" >
public imageUrl:string="https://dss0.baidu.com/73t1bjeh1BF3odCf/it/u=3093620924,1794231155&fm=85&s=BA917F81683046017AA9ADCC0300C023"

4、事件

4-1 (click)

<p (click)="handleClick()">{{msg}}</p>
export class HeaderComponent implements OnInit {
  ....
  public msg:string ="我喜欢写代码"
  constructor() { }
  ngOnInit() {
  }
  handleClick(){
    this.msg = "change"
  }
}

4-2 (keyup)

<input type="text" (keyup)="handleEnter($event)">
handleEnter(event:any){
    console.log(event.keyCode)
}

4-3 (keyup.enter)

<input type="text" #box (keyup.enter)="handleEnter(box.value)">
handleEnter(value:string){
    console.log(value)
}

5、请求数据

app.module.ts配置

import {HttpClientModule} from '@angular/common/http'
imports: [
    BrowserModule,
    HttpClientModule
  ],

5-2 在发送http请求的组件中配置HttpClient,作为构造函数的参数设置

import { Component, OnInit } from '@angular/core';
import {HttpClient} from '@angular/common/http'             //////
...
export class ContentComponent implements OnInit {
  constructor(public http:HttpClient) { }                   //////
  ngOnInit() {
    var url:string = "http://192.168.14.15:5000/dj/program?rid=336355127"
    this.http.get(url).subscribe(res=>{
      console.log(res)
    })
  }
}

5-1 请求本地数据

import cartList from './data'
...
public cartList:any = cartList   //方便数据渲染
...
constructor() {
  console.log(cartList)
}

5-2 请求数据

<div *ngFor='let item of programs'>
    <p>{{item.name}}</p>
    <img [src]="item.coverUrl">
</div>
import {HttpClient} from '@angular/common/http'
...
export class ContainerComponent implements OnInit {
  public programs:any;            //放置请求到的数据
  constructor(public http:HttpClient) {  }
                                  //请求数据
  ngOnInit() {
    var url:string = "http://192.168.14.15:5000/dj/program?rid=336355127"
    this.http.get(url).subscribe(res=>{
      console.log(res['programs'])
      this.programs = res['programs']
    })
  }

6、使用api 库(antd)

导入antd(自动构造)

终端:
ng add ng-zorro-antd

Angular 框架 - 图1
yyy zh_US

<button nz-button nzType="primary">Primary</button>

二、组件

2-1 组件创建

ng g component componets/xxxxx

2-2 组件注册

@NgModule({
  // 注册组件
  declarations: [
    AppComponent,
    HeaderComponent,   //注册header 组件
    ContentComponent   //注册content 组件
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})

2-3 组件使用

//app.component.html

<app-header></app-header>
<app-content></app-content>

image.png

2-4 父子组件传值 父传子组件

.html

<p>{{title}}</p>
//子组件:Input
import { Component, OnInit ,Input} from '@angular/core';
...
@Input() title:string;

父组件:app.component.ts

<app-header [title]="title"></app-header>
export class AppComponent {
  public title:string = 'hello ';
}

三、路由

angular-cli 中选中路由,之后app.component.html会多出

相当于vue中

3-1 路由

3-1-1 配置

一级路由
路由重定向
不匹配路由的处理(404)

//app-outing.module.ts中配置
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './components/home/home.component';
import { NewsComponent } from './components/news/news.component';
import { AboutComponent } from './components/about/about.component';
import { ErrorComponent } from './components/error/error.component';
const routes: Routes = [
  {
    path:'home',
    component:HomeComponent
  },{
    path:'news',
    component:NewsComponent
  },{
    path:"about",
    component:AboutComponent
  },{
      //路由重定向
    path:"",
    redirectTo:"home",
    pathMatch:"full"
  },{
    // 匹配没有设置的路由
    path:"**",
    component:ErrorComponent
  }
];
...
export class AppRoutingModule { }

3-1-2 路由导航 ( routerLinkActive设置routerLink默认选中的路由)

<ul>
  <li><a [routerLink]="['/home']"  routerLinkActive="router-link-active">home</a></li>
  <li><a [routerLink]="['/news']"  routerLinkActive="router-link-active">news</a></li>
  <li><a [routerLink]="['/about']" routerLinkActive="router-link-active">about</a></li>
</ul>

3-1-3 get传值

6-3-1 跳转:
<a [routerLink]="['/detail']" [queryParams]="{id:id}">跳转detail</a>
//id 
plublic id:string="213"
--------------------
//接收传参 接收this.route.queryParams
6-3-2 接收 this.route.queryParams
//导入正在显示的路由
import {ActivatedRoute} from '@angular/router'
export class DetailComponent implements OnInit {
  //构造函数中配置
  constructor(public route:ActivatedRoute) {  }

  ngOnInit() { 
      //subscribe触发
    this.route.queryParams.subscribe(res=>{
      console.log(res)
    })
  }
}

3-2 动态路由

配置
跳转传值
接收参数

7-1 配置
//app-routing.module.ts
{
    path:"detail/:id",
    component:DetailComponent
}
7-2 跳转传值
//第一种跳转方式
<a [routerLink]="['/detail',id]" >跳转detail</a>   跳转接收queryParams

//第二种跳转方式
<a routerLink="/detail/{{id}}" >跳转detail</a>
7-3 接收参数 this.route.params
import {ActivatedRoute} from '@angular/router'   //导入正在显示的路由
...
export class DetailComponent implements OnInit {

  constructor(public route:ActivatedRoute) { }   //构造函数的配置

  ngOnInit() {
   this.route.params.subscribe(res=>{            //subscribe 触发
     console.log(res)
   })
  // this.route.queryParams.subscribe(res=>{
  //   console.log(res)
  // })
  }
}

3-3 跳转事件(this.router.navigate)

3-3-1 动态路由的事件跳转

<button (click)="handleClick()">跳转detail</button>
//导入路由
import {Router} from "@angular/router"
export class HomeComponent implements OnInit {
  public id:string = "1213"
  //配置
  constructor(private router:Router) { }
  handleClick(){
    //跳转
    this.router.navigate(['/detail',this.id])
  }
}

3-3-2 get传值的事件跳转

<button (click)="handleClick()">跳转detail</button>
//导入NavigationExtras
import {Router,NavigationExtras} from "@angular/router"
...
//配置 NavigationExtras的参数
export class HomeComponent implements OnInit {
  public id:string = "1213"
  constructor(private router:Router) { }
  handleClick(){
    let navigationExtras:NavigationExtras ={
      queryParams:{
        "id":this.id
      }
    }
    //跳转
    this.router.navigate(['/detail'],navigationExtras)
  }
}

3-4 子路由

{
    path:'news',
    component:NewsComponent,
    children:[
      {
        path:"morning",
        component:MorningComponent
      },{
        path:"night",
        component:NightComponent
      },{
        path:"",
        redirectTo:"morning",
        pathMatch:"full"
      }
    ]
  }
//在父路由对应的组件中的html中
<router-outlet></router-outlet>

四、service

1-1 生成服务

ng g //检查组件
ng g service services/common

1-2 在跟模块中配置

app.module.ts

import { AboutComponent } from './components/about/about.component';
import { CommonService} from './services/common.service';        ////////

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    AboutComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [CommonService],                                    ///////
  bootstrap: [AppComponent]
})
export class AppModule { }

1-3 组件使用服务

//home.component.ts
//使用:

import { Component, OnInit } from '@angular/core';
import { CommonService } from '../../services/common.service'       //////1.导入服务
@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  constructor(public common:CommonService) { }                    //////2.构造函数中配置

  ngOnInit() {
    console.log(this.common.defaultCity)                           //////3.使用
  }
}

//home.component.ts

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class CommonService {
public defaultCity:string = "武汉"                                 /////
  constructor() {  }
}

1-4 城市例子:

点击获取数据 改变数据 缓存数据

<p>home works!</p>
<p>{{city}}</p>
<h2>热门城市</h2>
<button *ngFor = "let item of hotCities" class="btn"              //////
(click) = "handleClick(item)">                                         |
{{item}}                                                               |
</button>                                                         //////
//home.component.spec.ts
export class HomeComponent implements OnInit {
public city:any;
public hotCities:string [] = ["北京","上海","深圳","广州"]   ///////
  constructor(public common:CommonService) { }

  ngOnInit() {
    this.city = this.common.defaultCity
  }
  handleClick(item:string){          //////
     console.log(item)
  }
}

改变数据
//common.service.ts

public defaultCity:string = "武汉"

缓存数据
home

export class HomeComponent implements OnInit {
public city:any;
public hotCities:string [] = ["北京","上海","深圳","广州"]
  constructor(public common:CommonService) { }

  ngOnInit() {
    // this.city = this.common.defaultCity
    this.city = this.common.getCity();              //获取缓存
  }
  --------------1.-----|
  handleClick(item:string){
     console.log(item)
     this.common.changeCity(item);                  //改变缓存
  }
  ----------------2.-----|
   ngDoCheck(){
    console.log(1)
    this.city = this.common.getCity();             //改变缓存
  }
   //serve
export class CommonService {
public defaultCity:string = "武汉"
  constructor() {  }
  getCity(){                             //如果有缓存 获取缓存
    if(localStorage.getItem("city")){
      // 获取缓存
      this.defaultCity = localStorage.getItem("city")
    }
    return this.defaultCity;
  }
  changeCity(value:string){             //点击设置缓存
    this.defaultCity = value;
    // 设置缓存
    localStorage.setItem("city",value);
  }

五、路由模块

5-1 配置一个路由模块

ng g module views/home --routing
ng g component views/home //配置主组件

5-2 配置模块中的路由

//home-routing.module.ts
import { HomeComponent } from './home.component';
const routes: Routes = [
  {
    path:"",
    component:HomeComponent
  }
]

5-3 配置主路由

const routes: Routes = [
  {
    path:"home",
    loadChildren:()=>import('./views/home/home.module').then(m=>m.HomeModule)
  }
];