美文网首页
Angular2——小结

Angular2——小结

作者: monkeyying | 来源:发表于2019-04-13 14:49 被阅读0次

入坑

前端开发者估计跟我的心思是一样的,刚对AngularJS写出了点头绪,懂了点皮毛,转眼升级版Angular4.x就出现了,心中是各种礼貌的问候的。。。

表情包1

默默擦眼泪。。。我们来看下要从哪几个方面入手。以下目录~

  • 路由
  • 指令
  • 组件
  • 模块
  • 服务

Angular抛弃了原本的 ng-controller指令、复杂的$scope,保留了路由嵌套、依赖注入机制。还有一些指令的写法,例如ng-click 改成(click) 、ng-repeat改成 *ngFor等等,后续指令篇会详细提出。Angular的最大改造是用Typescript为默认开发语言,组件化的思维。

入坑前需要了解一下Angular-Cli工具。在项目初始化的时候,可以开箱即用,搭配一系列完整的工具

npm install @angular/cli -g
ng new study-ng
cd study-ng
ng serve

打开package.json文件

    "@angular/animations": "^5.2.0",
    "@angular/common": "^5.2.0",
    "@angular/compiler": "^5.2.0",
    "@angular/core": "^5.2.0",
    "@angular/forms": "^5.2.0",
    "@angular/http": "^5.2.0",
    "@angular/platform-browser": "^5.2.0",
    "@angular/platform-browser-dynamic": "^5.2.0",
    "@angular/router": "^5.2.0",

  • @angular/common:
    • CommonModule:通用模块,包含内置指令ngIf,ngFor
  • @angular/core:包含多种常用的模块
    • NgModule(模块定义装饰器)
    • Component(组件定义装饰器)
    • Directive (指令定义装饰器)
    • ElemtRef (元素引用)
    • ViewChild (获取子元素)
    • Output Input EventEmitter Render 等等等。。。。
  • @angular/forms:
    • Validators:表单校验
  • @angular/http:
    • HttpModule:http请求模块
  • @angular/router:
    • RouterModule:路由模块

天啊噜!!太多了。~~ps:这些都是撸过代码后从头看理论概念的时候能理解透的。。。硬生生的啃文字,小火鸡我是受不了的。。。

表情包2

生命周期

组件周期钩子函数 说明
constructor(myService:MyService) 类的构造器会再其他生命周期函数前调用,在该方法中完成服务的依赖注入
ngOnChanges 当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在 ngOnInit之前。(@input属性(输入属性)发生变化时,会调用。非此属性,不会调用。)
ngOnInit 只执行一次,dom操作可放在其中
ngDoCheck 更新检测机制,如果组件内发生异步事件,就会检查整个组件树
ngAfterContentInit 组件内容初始化之后调用
ngAfterContentChecked
ngAfterViewInit 组件视图初始化后调用
ngAfterViewChecked
ngOnDestroy 实例被销毁前调用,仅调用一次

进入正文啦 ~


image.png

一、路由篇

1、route设置三步走

(1)、手动添加路由文件

image

appRoutes的配置

import { Routes } from "@angular/router";
//引入组件等。。。。
import { ChildComponent } from'./home/child/child.component'

//定义并输出常量路由
export const appRoutes:Routes=[
  //地址栏输入 .../example,加载组件ExampleComponentComponent
  { path:'example',component:ExampleComponentComponent},
  { path:'home',
    component:HomeComponent,
    children:[{//子路由   .../home/home-child,加载ChildComponent组件
      path:'child',
      component:ChildComponent,
      //children:...
    }]
  },
  { path:'home/brother',component:BrotherComponent},//下图示例
  {
    //如果 地址栏没输入定义的路由就跳转到home路由界面
    path:'',
    redirectTo:'home',
    pathMatch:'full'
  }
]

子路由的区别

child组件是通过一级路由被载入到homeComponent的html模板的<router-outlet>下方

  <div routerLink="/example">栗子</div>

  <div routerLink="./brother">brother</div>

  <div routerLink="child">child的内容会展示在当页面  router-outlet  中</div>
  <!-- <div [routerLink]="['./child']">child的内容会展示在当页面---另一种写法</div> -->
  <router-outlet></router-outlet>

<router-outlet>路由占位符,可以理解为渲染路由组件的区域,一个组件只有一个无名的<router-outlet>可以有多个有名的<router-outlet>,例如:<router-outlet name=”a”><router-outlet name=”b”>

(2)、app.module.ts文件中引用

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'
import { appRoutes } from './route.module'
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    //注入模块中,forChild只能用于子路由,forRoot只能用于根模块
    // forRoot有一个可选的配置参数,里面有四个选项
    // enableTracing :在console.log中打印出路由内部事件信息
    // useHash :把url改成hash风格 /#/
    // initialNavigation : 禁用初始导航,没用过。。
    // errorHandler :使用自定义的错误处理,来抛出报错信息;
    RouterModule.forRoot(appRoutes,{useHash: true}),   //添加 !!
    BrowserModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

(3)、在index.html中添加

<body>
  <app-root></app-root>
</body>

2、其他注意点

(1)、路由跳转中可加上参数

import { Component, OnInit } from '@angular/core';
import {  Router } from '@angular/router';

@Component({
 //忽略...
})
export class HomeComponent implements OnInit {

  constructor(
    public router:Router
  ) { }

  goTopage(page,queryParams){
    this.router.navigate([page],{ queryParams: queryParam })
  }
}

ps:可通过navigate()方法来实现页面跳转

(2)、forChild的使用

根模块中使用forRoot(),子模块中使用forChild()

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
export const routes: Routes = [];

@NgModule({
  imports: [
    RouterModule.forChild(routes)
  ],
  // ...
})
export class ChildModule {  }

二、指令篇

  • 结构指令

1、 NgClass:接收一个对象,key为class名,value为值,表示是否用改样式

<p [ngClass]="{'fadeIn'}">example</p>
<p [ngClass]="{'fadeIn':!hidden}">example</p>

2、NgStyle:设置dom元素的css属性,可以动态的

<div [ngStyle]="{'color':'#999'}">写样式的东西咯</div>
<div [ngStyle]="{'color':gray?'#999':'#000'}">写样式的东西咯</div>

3、NgFor:创建dom元素,类似ng1中的ng-repeat

    const list = [ {name:'a'} ,{name:'b'}]
    const array = [1,2,3,4]
<ul>
    <li *ngFor="let item of list"></li>
</ul>
<ul>
    <li *ngFor="let item of array,let i = index">第个</li>
</ul>

4、NgIf:设置dom元素的展示或隐藏

<div *ngIf="show">要不要展示咧?<div>
  • 自定义属性指令

当内置指令还不能满足实际业务场景时,Angular中提供了自定义指令来满足特定的场景需求

举个栗子:给用自定义属性的内容加点特殊处理

1、第一步,创建一个directive文件

ng generate directive child-directive

此时app.module中已增加ChildDirectiveDirective指令

2、第二步,在模块中引入我们定义的指令

//...
@NgModule({
  imports: [ BrowserModule ],
  declarations: [
    AppComponent,
    ChildDirectiveDirective//!!申明我们定义的指令
  ],
  bootstrap: [ AppComponent ]
})
//...

3、第三步,撸出directive的逻辑

import { Directive,ElementRef,Renderer2,Input } from '@angular/core';

@Directive({//@Directive装饰器指定了一个选择器名称,用于指出与此指令相关联的属性的名字
  selector: 'color,[color]'
})
export class ChildDirectiveDirective {
  @Input('color')color : any;//@Input 为组件提供数据
  private elem;
  constructor(private renderer:Renderer2,elementRef:ElementRef) { 
    this.elem = elementRef//elementRef可直接获取到dom
  }
  ngOnInit(){
    this.renderer.setStyle(this.elem.nativeElement,'color',this.color)//让页面上该dom渲染该样式
  }
}

4、第四步,在html中引用该自定义属性

组件中添加该指令,可自定义展示的样式

<div [color]='"red"'>测试下咯</div>

三、组件

是时候祭出我的超简单基础组件第一套!!!switch组件的实现

look look 组件实现的部分

  • 1、 第一步,实现switch的样式

首先把switch轮子的样式写好


  • switch.component.html
    <span>
    <label class="iSwitch">
      <input type="checkbox" (click)="switch($event)" #switchInput >
      <i></i>
    </label> 
    </span>
    
    

具体css样式怎么撸的我就不贴了,自行撸!下面主要讲组件的实现

  • 2、 第二步,实现switch轮子的逻辑
  • switch.component.ts
import { Component, OnInit, Output, EventEmitter, Input, ViewChild,ElementRef,Renderer2 } from '@angular/core';

@Component({
    selector:'switch',//selector就是使用该组件时候的标签名字
    templateUrl:'./switch.component.html',
    styleUrls:['./switch.component.scss']
})

export class SwitchComponent implements OnInit {
  public open:boolean;
  @ViewChild('switchInput' , {read: ElementRef}) switchInput: ElementRef;
  //ElementRef 直接获取了轮子中<input>dom元素
  @Output() onchange: EventEmitter<any> = new EventEmitter<any>();
  //前面提到@input,可以从demo子组件中获取数据,@output则相当于方法的绑定,将onchange方法绑定到demo中,在父作用域中处理事件。output一般都是一个EventEmitter实例,通过emit()方法将父组件取到的值返回给demo子组件中
  constructor(private renderer: Renderer2 ,) { }
  ngOnInit() {
  }
  switch(e){
    this.open = !this.open
    this.onchange.emit(this.switchInput.nativeElement.checked)//返回给子组件demo中
  }
}

  • 3、 第三步,使用轮子的方式

使用轮子的代码,使用的方法:

demo.component.html

<switch (onchange)="getSwitchVaule($event)"></switch>

demo.component.ts

 export class SwitchDemo { 
  public getSwitchVaule(v){
    //页面中的onchange方法是父组件提供的 
    console.log(‘结果:’,v) 
  }
}

暂停一下,来一些啰嗦!!

看到这是否还会一脸懵逼???我们来解读下实现的过程。

使用<switch>标签名,可以实例化一个switch组件。</p>

获取到父组件通过@Output提供的onchange方法,在这个方法中,<switch>父组件处理switch开关的值,处理后的值。通过emit()方法返还给demo组件中的 public getSwitchVaule(v)方法中

  • 4、第四步,给轮子增加点初始值

接着我们就会思考switch组件是否可以添加一些默认值,进入页面默认就是打开的状态。

也就是demo组件如何给父组件通信,告诉父组件我现在是打开的状态,这里可以借助添加属性的方法来实现

<switch (onchange)="getSwitchVaule($event)" [default]=true>

[defalut]是一个自定义的属性,并且传值true,可在父组件轮子中去获取demo的传值

//...
export class SwitchComponent implements OnInit {
  @Input('default') defaultData: any;//默认关闭状态
  constructor(...) { }
  ngOnInit(){
    this.initDefault();//设置一个获取初始默认值的函数
  }
  initDefault(){
    //this.defaultData 可获取到demo组件中传值过来的true
    if(this.defaultData){
      this.switchInput.nativeElement.checked = true;//设置页面switch的开关状态
      this.open = !this.open
    }
  }
} 
//...

  • 5、最后一点,自行思考!!!

现在switch组件已经可以支持点击打开或者关闭开关,并且可接收一个默认开关值。至于switch的禁用状态disabled也同理可实现,这个大家就自行思考啦~道理都是一样的啦 ~~~

四、模板

五、服务

相关文章

网友评论

      本文标题:Angular2——小结

      本文链接:https://www.haomeiwen.com/subject/phglwqtx.html