angular组件与模版

本文详细介绍了Angular的组件与模板的使用,包括显示数据的方法如插值表达式、ngFor和ngIf,模版语法中的HTML、插值表达式、属性绑定、事件绑定等,以及组件的生命周期钩子、组件间交互、样式和属性指令的运用。重点讲解了如何通过属性和事件进行父子组件间的通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 显示数据

1.1 使用插值表达式显示组件属性

要使用插值表达式,就把属性名包裹在双花括号里放进视图模板,如 {{myHero}}。

1.2 使用ngFor显示数组属性

*ngFor 是 Angular 的“迭代”指令

export class AppComponent {
  title = 'Tour of Heroes';
  heroes = ['Windstorm', 'Bombasto', 'Magneta', 'Tornado'];
  myHero = this.heroes[0];
}
<h1>{{title}}</h1>
  <h2>My favorite hero is: {{myHero}}</h2>
  <p>Heroes:</p>
  <ul>
    <li *ngFor="let hero of heroes">
      {{ hero }}
    </li>
  </ul>

1.3 通过ngIf进行条件显示

有时,应用需要只在特定情况下显示视图或视图的一部分,这个时候使用ngif

<p *ngIf="heroes.length > 3">There are many heroes!</p>

2. 模版语法

2.1 模版中的html

HTML 是 Angular 模板的语言。几乎所有的 HTML 语法都是有效的模板语法。 但值得注意的例外是

2.2 插值表达式

插值表达式{{…}}可以把计算后的字符串插入到 HTML 元素标签内的文本或对标签的属性进行赋值。

<p>The sum of 1 + 1 is {{1 + 1}}</p>

表达式还可以调用宿主组件的方法,就像下面用的 getVal():

<p>The sum of 1 + 1 is not {{1 + 1 + getVal()}}</p>

2.3 模版表达式

模板表达式产生一个值。 Angular 执行这个表达式,并把它赋值给绑定目标的属性,这个绑定目标可能是 HTML 元素、组件或指令。

典型的表达式上下文就是这个组件实例,它是各种绑定值的来源。 在下面的代码片段中,双花括号中的 title 和引号中的 isUnchanged 所引用的都是 AppComponent 中的属性。

{{title}}
<span [hidden]="isUnchanged">changed</span>

2.4 模版语句

模板语句用来响应由绑定目标(如 HTML 元素、组件或指令)触发的事件。 它出现在 = 号右侧的引号中,就像这样:(event)=“statement”。

<button (click)="deleteHero()">Delete hero</button>

和表达式中一样,语句只能引用语句上下文中 —— 通常是正在绑定事件的那个组件实例。

典型的语句上下文就是当前组件的实例。 (click)=“deleteHero()” 中的 deleteHero 就是这个数据绑定组件上的一个方法。

模板语句不能引用全局命名空间的任何东西。比如不能引用 window 或 document,也不能调用 console.log 或 Math.max。

2.5 属性绑定

<img [src]="heroImageUrl">
<app-hero-detail [hero]="currentHero"></app-hero-detail>
<div [ngClass]="{'special': isSpecial}"></div>

注意需要加[]方括号。

下面的代码是等价的:

<p><img src="{{heroImageUrl}}"> is the <i>interpolated</i> image.</p>
<p><img [src]="heroImageUrl"> is the <i>property bound</i> image.</p>

在多数情况下,插值表达式是更方便的备选项。 实际上,在渲染视图之前,Angular 把这些插值表达式翻译成相应的属性绑定。

2.6事件绑定

可以通过 Angular 事件绑定来声明对哪些用户动作感兴趣

圆括号中的名称 —— 比如 (click) —— 标记出目标事件。在下面例子中,目标是按钮的 click 事件。

<button (click)="onSave()">Save</button>
<app-hero-detail (deleteRequest)="deleteHero()"></app-hero-detail>
<div (myClick)="clicked=$event" clickable>click me</div>

也可以使用on-前缀方式:

<button on-click="onSave()">On Save</button>
  • $event 对象
    在事件绑定中,Angular 会为目标事件设置事件处理器。绑定会通过名叫 $event 的事件对象传递关于此事件的信息。
<input [value]="currentHero.name"
       (input)="currentHero.name=$event.target.value" >

2.7 使用EventEmitter 实现自定义事件

通常,指令使用 Angular EventEmitter 来触发自定义事件。 指令创建一个 EventEmitter 实例,并且把它作为属性暴露出来。 指令调用 EventEmitter.emit(payload) 来触发事件,可以传入任何东西作为消息载荷。 父指令通过绑定到这个属性来监听事件,并通过 $event 对象来访问载荷。

2.8 双向绑定

在元素层面上,既要设置元素属性,又要监听元素事件变化。Angular 为此提供一种特殊的双向数据绑定语法:[(x)]。 [(x)] 语法结合了属性绑定的方括号[x] 和事件绑定的圆括号(x)。

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

2.9 模版引用变量( #var )

模板引用变量通常用来引用模板中的某个 DOM 元素,它还可以引用 Angular 组件或指令或Web Component。
使用井号 (#) 来声明引用变量。#phone 的意思就是声明一个名叫 phone 的变量来引用 元素。

<input #phone placeholder="phone number">

<!-- phone refers to the input element; pass its `value` to an event handler -->
<button (click)="callPhone(phone.value)">Call</button>

2.10输入和输出属性

输入属性是一个带有 @Input装饰器的可设置属性。当它通过属性绑定的形式被绑定时,值会“流入”这个属性。

输出属性是一个带有 @Output 装饰器的可观察对象型的属性。 这个属性几乎总是返回 Angular 的EventEmitter。 当它通过事件绑定的形式被绑定时,值会“流出”这个属性。

你只能通过它的输入和输出属性将其绑定到其它组件。

2.11 模版表达式操作符

模板表达式语言使用了 JavaScript 语法的子集,并补充了几个用于特定场景的特殊操作符。 下面介绍其中的两个:管道和安全导航操作符

2.11.1 管道操作符 ( | )

在绑定之前,表达式的结果可能需要一些转换。例如,可能希望把数字显示成金额、强制文本变成大写,或者过滤列表以及进行排序。

Angular 管道对像这样的小型转换来说是个明智的选择。 管道是一个简单的函数,它接受一个输入值,并返回转换结果。 它们很容易用于模板表达式中,只要使用管道操作符 (|) 就行了。

<div>Title through uppercase pipe: {{title | uppercase}}</div>

2.11.2 安全导航操作符 ( ?. ) 和空属性路径

Angular 的安全导航操作符 (?.) 是一种流畅而便利的方式,用来保护出现在属性路径中 null 和 undefined 值。 下例中,当 currentHero 为空时,保护视图渲染器,让它免于失败。

The current hero's name is {{currentHero?.name}}

2.11.3 非空断言操作符(!)

在 TypeScript 2.0 中,你可以使用 --strictNullChecks 标志强制开启严格空值检查。TypeScript 就会确保不存在意料之外的 null 或 undefined。
在这种模式下,有类型的变量默认是不允许 null 或 undefined 值的,如果有未赋值的变量,或者试图把 null 或 undefined 赋值给不允许为空的变量,类型检查器就会抛出一个错误

Angular 模板中的**非空断言操作符(!)也是同样的用途。

<div *ngIf="hero">
  The hero's name is {{hero!.name}}
</div>

3.生命周期

ngOnChanges()当 Angular(重新)设置数据绑定输入属性时响应。 该方法接受当前和上一属性值的 SimpleChanges 对象当被绑定的输入属性的值发生变化时调用,首次调用一定会发生在 ngOnInit() 之前。
ngOnInit()在 Angular 第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。Initialize the directive/component after Angular first displays the data-bound properties and sets the directive/component’s input properties.在第一轮 ngOnChanges() 完成之后调用,只调用一次。
ngAfterViewInit()初始化完组件视图及其子视图之后调用。第一次 ngAfterContentChecked() 之后调用,只调用一次。
ngOnDestroy()当 Angular 每次销毁指令/组件之前调用并清扫。 在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏。在 Angular 销毁指令/组件之前调用

3.1 OnInit钩子

使用 ngOnInit() 有两个原因:

  • 在构造函数之后马上执行复杂的初始化逻辑
  • 在 Angular 设置完输入属性之后,对该组件进行准备。

3.2 OnDestroy()钩子

一些清理逻辑必须在 Angular 销毁指令之前运行,把它们放在 ngOnDestroy() 中。

4. 组件之间的交互

4.1数据从父组件传到子组件

HeroChildComponent 有两个输入型属性,它们通常带@Input 装饰器。

import { Component, Input } from '@angular/core';
 
import { Hero } from './hero';
 
@Component({
  selector: 'app-hero-child',
  template: `
    <h3>{{hero.name}} says:</h3>
    <p>I, {{hero.name}}, am at your service, {{masterName}}.</p>
  `
})
export class HeroChildComponent {
  @Input() hero: Hero;
  @Input('master') masterName: string;
}

父组件 HeroParentComponent。

import { Component } from '@angular/core';
 
import { HEROES } from './hero';
 
@Component({
  selector: 'app-hero-parent',
  template: `
    <h2>{{master}} controls {{heroes.length}} heroes</h2>
    <app-hero-child *ngFor="let hero of heroes"
      [hero]="hero"
      [master]="master">
    </app-hero-child>
  `
})
export class HeroParentComponent {
  heroes = HEROES;
  master = 'Master';
}

4.2 父组件监听子组件的事件

子组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件。

子组件的 EventEmitter 属性是一个输出属性,通常带有@Output 装饰器

子组件

import { Component, OnInit,Input,Output,EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  @Input() item;
//实例化事件对象
  @Output() childMsg=new EventEmitter()
  constructor() { }

  ngOnInit(): void {
  }
  sendMsg(){
    //发送消息
    this.childMsg.emit({msg:"我子组件,这是我发给父组件的消息"})
  }

}

<button (click)="sendMsg()">发送消息给父组件</button>

父组件

<app-child [item]="sendchildMsg" (childMsg)="getEvent($event)"></app-child>



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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  msg="1.00"
  sendchildMsg ="这是给子元素的数据,希望在子组件中显示";
  getChildMsg="";
  getEvent(event){
    console.log(event)
    this.getChildMsg = event.msg
  }
}

5. 组件样式

Angular 应用使用标准的 CSS 来设置样式。这意味着你可以把关于 CSS 的那些知识和技能直接用于 Angular 程序中,例如:样式表、选择器、规则以及媒体查询等。

有几种方式把样式加入组件:

  • 设置 styles 或 styleUrls 元数据
  • 内联在模板的 HTML 中
  • 通过 CSS 文件导入

6.属性指令

angular中有三种类型的指令:

  1. 组件 —— 拥有模板的指令
  2. 结构性指令 —— 通过添加和移除 DOM 元素改变 DOM 布局的指令
  3. 属性型指令 —— 改变元素、组件或其它指令的外观和行为的指令。

创建属性指令

ng generate directive highlight

编写代码,这个指令实现高亮元素:

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

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
    constructor(el: ElementRef) {
       el.nativeElement.style.backgroundColor = 'yellow';
    }
}

通过ElementRef访问目标元素。

使用属性型指令

<p appHighlight>Highlight me!</p>

使用 @Input 数据绑定向指令传递值

@Input() highlightColor: string;

<p appHighlight highlightColor="yellow">Highlighted in yellow</p>
<p appHighlight [highlightColor]="'orange'">Highlighted in orange</p>

绑定到 @Input 别名

可以使用Input的别名

@Input('appHighlight') highlightColor: string;
<p [appHighlight]="color">Highlight me!</p>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值