Angular学习笔记2--Api基础

路由

常用指令

npm i --save 包名:软件依赖  
npm i --save-dev 包名:开发依赖
ng new 项目名:新建Angular项目
ng new 项目名 --skip-install --style=scss:跳过依赖的安装
ng build -prod:生产环境编译
ng serve:启动开发服务器

npm install -g json-server:根据json生成rest API
json-server 文件位置:使用json-server

基本配置和使用

const routes: Routes = [
  // 基本配置
  { path: "index", component: IndexComponent },
  // 子路由
  { path: "user", component: UserComponent, children: [
    { path: "info", component: InfoComponent },
    { path: 'settings', component: SettingsComponent }
  ]},
  // 重定向
  { path: "", redirectTo: '/index', pathMatch: 'full' },
  // 通配符,其他路由失败的,会跳转到这个视图
  { path: '**', component: EmptyComponent }
];

路由跳转

// 1.利routerLink在html中直接跳转
<a [routerLink]="['/']">跳转到主页</a>
<a [routerLink]="['./settings']">跳转到设置页</a>
// 2.在ts文件中用Router进行跳转
<button (click)="skipToUser()" >跳转到用户页面</button>

constructor(private route: Router) { }
skipToUser() {
  this.route.navigateByUrl("user")
}

路由数据传递

在查询参数中传递数据

<a [routerLink]="['/user']" [queryParams]="{id:1}">跳转到用户页</a>

constructor(private route: ActivatedRoute) { }
ngOnInit() {
   console.log(this.route.snapshot.queryParams["id"]);
}

在路由路径中传递数据

<a [routerLink]="['/user', 1]">跳转到用户页</a>
// 路由配置
{ path: "user/:id", component: UserComponent }

constructor(private route: ActivatedRoute) { }
ngOnInit() {
   console.log(this.route.snapshot.params["id"]);
}

在路由配置中传递数据

<a [routerLink]="['/user']">跳转到用户页</a>

{ path: "user", component: UserComponent, data:[{id:2}] }

ngOnInit() {
  console.log(this.route.snapshot.data[0]["id"]);
}

ts文件中跳转传递数据

// A页面点击button跳转到B页面, 并在路径还参数中分别传递数据
// 1.A页面配置
<button (click)="skipToUser()">跳转到用户页</button>

constructor(private route: Router) { }
skipToUser() {
  this.route.navigate(['/user', 5], { queryParams: { id: 10 }});
}
// 2.路由配置
{ path: "user/:id", component: UserComponent }
// 3.B页面配置
constructor(private route: ActivatedRoute) { }
ngOnInit() {
// console.log(this.route.snapshot.params["id"]);
// console.log(this.route.snapshot.queryParams["id"]);
this.route.params.subscribe((params: Params) => {
  console.log(params["id"])
})
}

辅助路由(多页面公用聊天窗口)

// 1.html中代码
<router-outlet name="aux"></router-outlet>

{ path:'chat', component:ChatComponent, outlet:'aux' },
<a [routerLink]="[{outlets:{aux:'chat'}}]">开始聊天</a>
// 不显示
<a [routerLink]="[{outlets:{aux:null}}]">结束聊天</a>
// 同时跳转到home页面
<a [routerLink]="[{outlets:{primary:home, aux:'chat'}}]">开始聊天</a>

路由守卫

钩子函数

CanActivate: 处理导航到某路由的情况
CanDeactivate: 处理从当前路由离开的情况
Resolve: 在路由激活之前获取路由数据

当用户已经登录并拥有某些权限时才可以进入某些路由

1.实现CanActivate接口,返回boolean类型参数

export class Guard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>|Promise<boolean>|boolean {
   return undefined;
  }
}

2.配置路由参数

{ path: "index", component: IndexComponent, canActivate: [Guard] }

3.注入对象

@NgModule({
  providers: [Guard]
})

当用户未执行保存操作视图离开当前页,给用户提醒

实现CanDeactivate接口,注意泛型参数的传入,其他同上

export class UnsaveGuard implements CanDeactivate<IndexComponent> {
  canDeactivate(component: IndexComponent) {
    return window.confirm("还没有保存,确定要离开吗");
  }
}

当进入一个页面前,提前请求号数据,携带参数进入页面

1.实现Resolve接口,注意泛型的传入

export class UserResolve implements Resolve<User> {
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<User>|Promise<User>|User {
    return new User('123', '张三');
  }

2.定义model类

export class User {
  constructor(public id: string, public name: string) {}
}

3.路由配置和注入对象同上
4.数据接收

constructor(private route: ActivatedRoute) { }
  public userId: string;
  public userName: string;
  ngOnInit() {
    this.route.data.subscribe((data: [User]) => {
      this.userId = data[0].id;
      this.userName = data[0].name;
    })
  }

依赖注入

基本用法

1.创建服务

ng g service product/product

2.编写服务

getProduct(): Product {
  return new Product('123', 'productName')
}
getProduct(): Product {
    return new Product('123', 'productName')
  }

3.添加配置

@NgModule({
  providers: [ProductService]
})

4.使用

private productId: string;
private productName: string;
constructor(private productService: ProductService) {
}
ngOnInit() {
  this.productId = this.productService.getProduct().id;
  this.productName = this.productService.getProduct().name;
}

基于原有服务提供的服务

1.创建服务
2.编写服务

export class AnotherProductService implements ProductService{
  getProduct(): Product {
    return new Product("aaaaa", "another-product");
  }
}

3.在component中添加配置

@Component({
  providers: [{provide: ProductService, useClass: AnotherProductService}]
})

4.使用

private productId: string;
private productName: string;
constructor(private productService: AnotherProductService) { 
ngOnInit() {
  this.productId = this.productService.getProduct().id;
  this.productName = this.productService.getProduct().name;
}

工厂函数提供器

providers: [{
    provide: ProductService,
    useeFactory: (logger: LoggerService, appConfig) => {
      if (appConfig.isDev) {
        return new ProductService(logger);
      } else {
        return new AnotherProductComponent(logger);
      }
    },
    deps: [LoggerService, "APP_CONFIG"]
  }, LoggerService, 
  {
    provide: "APP_CONFIG", useValue: {isDev: false}
  }]

数据绑定

事件绑定

<input (input)="onInputEvent($event)">
<button (click)="saved = true">

属性绑定

<img [src]="imgUrl">
<img src="{{imgUrl}}">
<tr><td [attr.colspan]="size">html属性绑定</td></tr>
// 完全替换class中的内容
<div class="aaa bbb" [class]="someExpression">something</div>
// 值为true时,绑定special样式
<div [class.special]="isSpecial">something</div>
// 同时控制多个css类是否显示
<div [ngClass]="{aaa:isA, bbb:isB}">
// 样式绑定
<button [style.color]="isSpecial ? 'red' : 'green'">Red</button>
<div [ngStyle]="{'font-size':this.canSave?'italic':'normal'}">

双向绑定

<input [(ngModel)]="name">

管道

1.创建管道

ng g pipe pipe

2.编写规则

export class PipePipe implements PipeTransform {
  transform(value: any, args?: any): any {
    return value == 1 ? "合格" : "不合格";
  }
}

3.使用

<p>{{ num | pipe}}</p>

组见间通信

父组件向子组件传值

父组件

<app-son [fatherName]="'fatherName'">

子组件

  @Input()
  public fatherName: string;

子组件向父组件传值

子组件

@Output('sonEmit')
emitter: EventEmitter<string> = new EventEmitter();
emitData() {
  this.emitter.emit("子组件中的数据");
}

父组件

<app-son (sonEmit)="receiveData($event)"></app-son>
receiveData(data: string) {
  console.log(data);
}

用服务作为中间人传递数据

生命周期钩子

生命周期函数

红色只会调用一次,绿色会调用多次。

constructor:构造器函数,一般用于注入服务

ngOnChanges:检测到输入数据变化,首次触发发生在ngOnInit前。注意对象的属性发生变化时监听不到 (监测对象地址 )

ngOnInit:组件初始化,通常会设置一些初始值

ngDoCheck:变更监测时触发,input框的点击也会触发。

ngAfterContentInit:被投影的内容初始化完毕时调用(先父后子)

ngAfterContentChecked:被投影的内容变更监测完毕时调用

ngAfterViewInit:子组件初始化之后 ,不能做数据更新的操作(先子后父)

ngAfterViewChecked:子组件发生变化检测之后,不能做数据更新的操作

ngOnDestroy:组件注销时的清理工作,通常用于移除事件监听,退订可观察对象等

变更监测

投影(父组件中的布局显示在子组件中)

1.定义父组件的内容

<app-son>
  <div class="header">这是父组件中的头部</div>
  <div class="footer">这是父组件中的尾部</div>
</app-son>

2.定义子组件的投影点

<ng-content select=".header"></ng-content>
<ng-content select=".footer"></ng-content>

http请求(代理配置和使用)

1.根目录下创建proxy.config.json文件,写入代码

{
  "/api": {
    "target": "http://www.classcool.net",
    "secure": false,
    "changeOrigin":true,
    "pathRewrite": {
      "^/api": ""
    }
  }
}

2.更改启动配置文件:package.json,在scripts的start里面加入代理配置

"scripts": {
    "start": "ng serve --proxy-config proxy.config.json"
  }

3.app.module.ts中引入HttpclientModule

@NgModule({
  imports: [
    HttpClientModule
  ]
})

4.使用

  dataSource: Observable<any>;
  products: any;
  constructor(private http: HttpClient) {
    this.products = this.http.get<any>('/api/user/info').subscribe(data => console.log(data));
    console.log(this.dataSource);
  }

模块只初始化一次的方式

import { NgModule, SkipSelf, Optional } from '@angular/core';

export class CoreModule {
    constructor(@Optional() @SkipSelf() parent: CoreModule) {
        if (parent) {
            throw new Error('模块已经存在,不能再次加载!')
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值