angular ngoninit 刷新html页面_快速地上手Angular组件开发

  • Post author:
  • Post category:其他


如果我会一些Javascript的基础知识,我可以

快速地上手Angular

吗?或者说,我是一名前端工作者,没有接触过Angular,我该如何

快速地使用Angular进行日常开发

呢?我是轻流前端团队的一员,用了一周的时间从之前没有使用过Angular到了解Angular 可以进行一些简单的开发,在这之中收获良多,希望可以给同样想了解和使用Angular的小伙伴带来一些参考。

1. 组件是什么?

组件(Component),就是可以实现我们需求的一个小块。一个自定义的按钮、一个表单、一个页面等等,都是组件。组件是Angular项目的核心概念,我们页面的一切都是由一个一个的组件搭建起来的。组件化的目的有两个:一是解耦,把逻辑封装在内部,每一个组件都是功能相对单一和独立的个体;二是复用,封装成组件之后不仅可以在项目内部复用,甚至可以沉淀下来跨项目复用。

// 以一个简单的button为例
@Import { Component } from ‘@angular/core’;
@Component({
  selector: 'demo-button',
  template: `<button class="demo-btn">{{btnText}}</button>`,
  styles: [
    `.demo-btn {
      color: red;
    }`
  ]
})
export class DemoButtonComponent {
  btnText: 'click me';
}

上面就是一个很简单的组件,一个文字为红色的’click me’的按钮,在页面中使用也很简单:

<body>
  <demo-button></demo-button>
</body>

上面的代码中,我们注意到,从@angular/core中导入了 Component,并且使用@Component() 这个修饰器说明了我们的 DemoButtonComponent 是一个组件。@Component() 中我们传入了几个配置项 selector、template、styles,我们分别讲一下它们是什么意思:

selector:顾名思义,它是一个选择器(与css选择器用法一样),选择什么呢?选择什么样的标签会触发我们DemoButtonComponent这个类的构造。

template:即我们这个组件的模板,除了使用template这个属性,我们还可以使用templateUrl这个可选属性,可以导入一个html文件作为模板。

styles:组件内部样式。这是一个数组,除了项demo中使用,也可以导入样式文件。

@Component({
  selector: 'demo-button',
  templateUrl: './demo-button.html'
  styles: [
    `demo-btn: { color: red }`,
    './demo-button.scss'  
  ]
})

那么,我们如何在组件中做更多的事情呢?我们再看Angular的生命周期钩子。

2. Angular生命周期钩子

Angular生命周期钩子​angular.cn

Angular组件的生命周期中,暴露八个回调函数在不同的阶段给开发者使用(类似于window对象的onload、ready),分别为:

891d953863d2acd0596e94bf854896c4.png

在代码中使用钩子:

@Import { Component,OnInit, OnDestroy } from ‘@angular/core’;
@Component({
  selector: 'demo-button',
  template: `<button class="demo-btn">{{btnText}}</button>`,
  styles: [
    `.demo-btn {
      color: red;
    }`
  ]
})
export class DemoButtonComponent implements OnInit, OnDestroy {
  btnText: string;

  ngOnInit(): void {
    this.btnText = 'click me';
  }

  ngOnDestroy(): void {
    //do something
  }
}

这样,我们就可以通过Angular暴露给我们的这些生命周期钩子,在组件生命周期的不同阶段去做不同的事情,比如组件的初始化、事件监听的销毁等等。

3. 组件通信

因为Angular项目中,页面是由一个一个的组件搭建而成,整个架构是纵向分层的。我们可以把一个页面想像成一个组件树,小组件构成更大一些、功能更丰富的组件,大一些的组件构成了页面的一些功能块,最终的页面是由组件一级一级地构建而成。所以,数据的传输、组件之间的通信是我们必须要解决的一个问题,那么这个问题Angular是如何解决的呢?Angular给我们提供了两种方式。

3.1 Input和Output(输入输出)

我们先来写两个简单的父子组件:

@Import { Component, EventEmitter, Input, Output } from ‘@angular/core’;
@Component({
  selector: 'demo-input',
  template: `
    <input [(ngModel)]="value" type="{{inputType}}"><button (click)="ok()">ok<button>
  `
})
export class DemoInputComponent {
  @Input() inputType: string;
  @Output() onOk: EventEmitter<string> = new EventEmitter();

  value: string;

  ok(): void {
    this.onOk.emit(this.value);
  }
}

@Import { Component } from ‘@angular/core’;
@Component({
  selector: 'demo-form',
  template: `
    userName: <demo-input [inputType]="'text'" (onOk)="name = $event"></demo-input>
    passWord: <demo-input [inputType]="'password'" (onOk)="pwd = $event"></demo-input>
  `
})
export class DemoFormComponent {
  name: string;
  pwd: string;
}

在这两个组件中,我们在父组件的模板中 使用 ‘[inputType]’ 向子组件中输入了inputType属性,并在子组件中使用 ‘@Input()’ 接受了这个输入的属性。在子组件中,点击按钮时,使用’@Output()’事件发射器向外发射了’onOk’事件,然后在父组件中使用 ‘(onOk)’ 接受到了这个发射出来的事件。

我们可以使用input和output在父子组件中方便快捷地进行通信。

3.2 Service

父子组件可以使用Input和Output方便地通信,非父子节点呢?如果使用Input和Output层层传递进行通信的化,代码会非常的难看,有没有什么别的方法可以更方便地进行组件通信呢?

当然有,那就是我们的service(服务)。同样看一个例子:

@Import { Component, OnInit } from ‘@angular/core’;
@Component({
  selector: 'demo-input',
  template: `
    <input [(ngModel)]="value" type="{{inputType}}"><button (click)="ok()">ok<button>
  `
})
export class DemoInputComponent implements OnInit {
  inputType: string;
  value: string;

  constructor(public formSrv: FormService ) {}

  ok(): void {
    this.formSrv.onOk.emit(this.value);
  }


  ngOnInit(): void {
    this.inputType = this.formSrv.inputType;
  }
}

@Import { Component, OnInit } from ‘@angular/core’;
@Import { FormService } from './form.service.ts';
@Component({
  selector: 'demo-form',
  template: `
    userName: <demo-input></demo-input>
  `
})
export class DemoFormComponent implements OnInit {
  name: string;
  
  constructor(public formSrv: FormService ) {
    this.formSrv.onOk.subscribe(res => {
      this.name = res;
    });
  }

  ngOnInit(): void {
    this.formSrv.inputType = 'text';
  }

}

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

@Injectable({
  providedIn: 'root'
})

export class FormService {
  inputType: string;
  onOk: EventEmitter<string> = new EventEmitter();
}

在这个service中,我们把它的’providedIn’设置为‘root’,表示这个类在整个项目中是单例的,所以我们可以用它来存放一些组件公用的数据或者状态。当然这个的写法并不标准,在Angular中的Module和Compnent中都可以配置provider,即相对于每一个module或者component都会生成一个service实例。

结尾

作为三大前端框架之一,Angular的强大毋庸置疑,我们都是学习者和探索者(甚至是创造者),还有很多东西我现在也没有搞清楚,不过只要我们有心并且能付诸行动,必定天堑变通途。



版权声明:本文为weixin_28692817原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。