0

0

聊聊angular10中模板如何进行数据绑定?

青灯夜游

青灯夜游

发布时间:2021-08-03 10:31:57

|

2316人浏览过

|

来源于掘金社区

转载

本篇文章给大家介绍一下angular10模板的数据绑定,带大家了解一下三种绑定语法、模板/插值表达式、属性绑定、样式绑定、事件绑定、双向绑定、内置指令、模板引用变量等等。

聊聊angular10中模板如何进行数据绑定?

绑定语法概览

绑定语法归纳起来大概有三种(基础)

  • model => view (单向:插值、属性绑定、样式绑定)
  • view  => model(单向:事件绑定)
  • view model(双向:ngModule)

【相关教程推荐:《angular教程》】


{{expression}}
[target]="expression"
bind-target="expression"

{{ msg }}

// 插值表达式 聊聊angular10中模板如何进行数据绑定? // 属性绑定 // 组件通过属性绑定的方式传参
// 样式绑定
Special
// class绑定 // Attribute绑定 (target)="statement" on-target="statement" // 元素事件 // 组件事件,用于监听子组件传递过来的参数
click me
// 指令事件 [(target)]="expression" bindon-target="expression" // 双向数据绑定

HTML attribute 与 DOM property 的对比(很重要,加强理解)

理解 HTML 属性和 DOM 属性之间的区别,是了解 Angular 绑定如何工作的关键。Attribute 是由 HTML 定义的。Property 是从 DOM(文档对象模型)节点访问的

  • 一些 HTML Attribute 可以 1:1 映射到 Property;例如,“ id”。
  • 某些 HTML Attribute 没有相应的 Property。例如,aria-* colSpan rowSpan。
  • 某些 DOM Property 没有相应的 Attribute。例如,textContent。

重要的是要记住,HTML Attribute 和 DOM Property 是不同的,就算它们具有相同的名称也是如此。 在 Angular 中,HTML Attribute 的唯一作用是初始化元素和指令的状态。

模板绑定使用的是 Property 和事件,而不是 Attribute。

编写数据绑定时,你只是在和目标对象的 DOM Property 和事件打交道。

注意:

该通用规则可以帮助你建立 HTML Attribute 和 DOM Property 的思维模型: 属性负责初始化 DOM 属性,然后完工。Property 值可以改变;Attribute 值则不能。

此规则有一个例外。 可以通过 setAttribute() 来更改 Attribute,接着它会重新初始化相应的 DOM 属性。

案例1:input

当浏览器渲染input时,它会创建一个对应的 DOM 节点,其 value Property 已初始化为 “Sarah”。

当用户在 input 中输入 Sally 时,DOM 元素的 value Property 将变为 Sally。 但是,如果使用 input.getAttribute('value') 查看 HTML 的 Attribute value,则可以看到该 attribute 保持不变 —— 它返回了 Sarah。

HTML 的 value 这个 attribute 指定了初始值;DOM 的 value 就是这个 property 是当前值。

案例2:禁用按钮

disabled Attribute 是另一个例子。按钮的 disabled Property 默认为 false,因此按钮是启用的。

当你添加 disabled Attribute 时,仅仅它的出现就将按钮的 disabled Property 初始化成了 true,因此该按钮就被禁用了。

添加和删除 disabled Attribute 会禁用和启用该按钮。 但是,Attribute 的值无关紧要,这就是为什么你不能通过编写 仍被禁用 来启用此按钮的原因。

要控制按钮的状态,请设置 disabled Property,


模板/插值表达式 {{}} (基础,掌握)

模版中除了绑定变量,还能绑定方法

模版中还可以写些简单的逻辑,比如判断或运算

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
      

变量绑定:{{ title }}

方法绑定:{{ getVal }}

方法绑定:{{ getVal2() }}

简单运算 {{ 1 + 1 }}.

简单运算 {{ price * 0.7 }}.

简单运算:{{ gender === 0 ? '男':'女' }}

与方法结合 {{ price * 0.7 + getVal }}.

与方法结合 {{ price * 0.7 + getVal2() }}.

`, }) export class AppComponent { title = "模板绑定"; price = 30; gender = 0; get getVal(): number { //es6新语法,函数可以当做变量来使用 return 20; } getVal2(): number { return 33; } }

当使用模板表达式时,请遵循下列指南:

  • 非常简单
  • 执行迅速
  • 没有可见的副作用(即模版中的逻辑不能改变组件的变量)

属性绑定(基础,掌握)

绑定图片

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
    madao
    madao // 推荐
    madao
    `,
  styles: []
})
export class AppComponent {
  madaoSrc = '../assets/images/madao.jpg';
}

绑定普通属性

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
    
     // 注意colSpan和colspan
        
name phone age
张三 13398490594 33
李四15079049984 22
`, styles: [] }) export class AppComponent { madaoSrc = '../assets/images/madao.jpg'; user = { name: 'madao', pic: this.madaoSrc }; colSpan = 2; isDisabled = false; }

绑定自定义属性

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
    一行文字
    test title
    test title
    `,
  styles: []
})
export class AppComponent {
  madaoSrc = '../assets/images/madao.jpg';
  customTitle = 'bbb';
}

使用插值表达式(不推荐)

插值也可以用于属性,但常规做法还是用中括号[],建议整个项目保持风格统一

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
    {{ user.name }}
    `,
  styles: []
})
export class AppComponent {
  madaoSrc = '../assets/images/madao.jpg';
  user = {
    name: 'madao',
    pic: this.madaoSrc
  };
}

样式绑定(属于属性绑定,基础,掌握)

绑定单个样式

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
      
      
      
      
         //false
        //false
    `,
  styles: []
})
export class AppComponent {
    theme = 'primary';
    isSuccess = true;
}

绑定多个class

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
      
      
      

      
      
      
      
    `,
  styles: []
})
export class AppComponent {
    btnCls = 'btn btn-primary';
    btnCls2 = ['btn', 'btn-success'];
    btnCls3 = {
      btn: true,
      'btn-info': true
    };
}

绑定单个style

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
      

一段文字

设置高度

设置高度

`, styles: [] }) export class AppComponent {}

绑定多个style

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
      

style1

style2

style3

style3

`, styles: [] }) export class AppComponent { style1 = 'width: 200px;height: 50px;text-align: center;border: 1px solid;'; style2 = ['width', '200px', 'height', '50px', 'text-align', 'center', 'border', '1px solid']; // 有问题 style3 = { width: '200px', height: '50px', 'text-align': 'center', border: '1px solid' }; }

绑定优先级

  • 某个类或样式绑定越具体,它的优先级就越高
  • 绑定总是优先于静态属性

事件绑定(基础,掌握)

基本用法

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
      
    `,
  styles: []
})
export class AppComponent {
    onClick() {
      console.log('onClick');
    } 
}

事件对象

$event 就是原生的事件对象

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
      
    `,
  styles: []
})
export class AppComponent {
    onClick(event: MouseEvent) {
      console.log('onClick', event.target);
      //直接用event.target.value会报错,要用类型断言
      console.log((event.target as HTMLInputElement).value)
    }
}

事件捕获或事件冒泡

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
      
//可以在html使用一些简单的语法
`, styles: [] }) export class AppComponent { parentClick() { console.log('parentClick'); } chilrenClick(event: MouseEvent) { event.stopPropagation(); //阻止事件冒泡 console.log('chilrenClick'); } }

输入输出属性(主要是子传父,通过自定义事件)

输入属性

子组件

import { Component, Input } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `

Today's item: {{item}}

` }) export class ItemDetailComponent { @Input() item: string; }

父组件

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
     
  `,
})
export class AppComponent {
  currentItem = 'Television';
}

输出属性

  • 通过 new EventEmitter() 自定义一个事件;
  • 调用 EventEmitter.emit(data) 发出事件,传入数据;
  • 父指令通过监听自定义事件,并通过传入的 $event 对象接收数据。

子组件

import { Component, Output, EventEmitter } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
             `,
})
export class ItemOutputComponent {
  @Output() newItemEvent = new EventEmitter(); //子传父,输出属性
  addNewItem(value: string) {
    this.newItemEvent.emit(value); //自定义事件触发
  }
}

父组件

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
      //监听自定义事件
  `,
})
export class AppComponent {
   items = ['item1', 'item2', 'item3', 'item4'];
    addItem(newItem: string) {
      this.items.push(newItem);
    }
}

在元数据中声明输入和输出属性

固然可以在 @Directive 和 @Component 元数据中声明 inputs 和 outputs,但不推荐提供别名

@Input()和@Output()可以接收一个参数,作为变量的别名,那么父组件中只能用别名绑定

子组件

import { Component, Input, EventEmitter, Output } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `

Today's item: {{item}}

` }) export class ItemDetailComponent { @Input('aliasItem') item: string; @Output('newItem') newItemEvent = new EventEmitter(); addNewItem(value: string) { this.newItemEvent.emit(value); } }

父组件

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
      //注意是监听的别名
  `,
})
export class AppComponent {
  currentItem = 'Television';
  items = ['item1', 'item2', 'item3', 'item4'];
  addItem(newItem: string) {
    this.items.push(newItem);
  }
}

输入属性一定要用中括号[]绑定?

如果绑定的值是静态的,就不需要[];为了统一风格尽量用上[]

盛世企业网站管理系统1.1.2
盛世企业网站管理系统1.1.2

免费 盛世企业网站管理系统(SnSee)系统完全免费使用,无任何功能模块使用限制,在使用过程中如遇到相关问题可以去官方论坛参与讨论。开源 系统Web代码完全开源,在您使用过程中可以根据自已实际情况加以调整或修改,完全可以满足您的需求。强大且灵活 独创的多语言功能,可以直接在后台自由设定语言版本,其语言版本不限数量,可根据自已需要进行任意设置;系统各模块可在后台自由设置及开启;强大且适用的后台管理支

下载
import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
     
  `,
})
export class AppComponent {
  // currentItem = 'Television';
}

双向绑定(基础,掌握)

先决条件

  • 组件的属性绑定
  • 组件的事件绑定
  • 输入和输出(父子组件通信)

基本的双向绑定

子组件

import {Component, OnInit, ChangeDetectionStrategy, EventEmitter, Input, Output} from '@angular/core';@Component({  selector: 'app-sizer',  template: `
    
`, styles: [ ], changeDetection: ChangeDetectionStrategy.OnPush })export class SizerComponent implements OnInit { @Input() size: number | string; // 想要用双向绑定语法,output变量名就一定是输入属性名加上Change @Output() sizeChange = new EventEmitter(); constructor() { } ngOnInit(): void { } dec() { this.resize(-1); } inc() { this.resize(+1); } resize(delta: number) { this.size = Math.min(40, Math.max(8, +this.size + delta)); this.sizeChange.emit(this.size); } }

父组件

import { Component } from '@angular/core';@Component({  selector: 'app-root',  template: `
     
     
Resizable Text
`, })export class AppComponent { fontSizePx = 16; }

双向绑定工作原理

为了使双向数据绑定有效,@Output() 属性的名字必须遵循 inputChange 模式,其中 input 是相应 @Input() 属性的名字。例如,如果 @Input() 属性为 size ,则 @Output() 属性必须为 sizeChange 。

上面的 sizerComponent 具有值属性 size 和事件属性 sizeChange。 size 属性是 @Input(),因此数据可以流入 sizerComponent 。 sizeChange 事件是一个 @Output() ,它允许数据从 sizerComponent 流出到父组件。

上面例子,有两个方法, dec() 用于减小字体大小, inc() 用于增大字体大小。这两种方法使用 resize() 在最小/最大值的约束内更改 size 属性的值,并发出带有新 size 值的事件。

简写形式

双向绑定语法是属性绑定和事件绑定的组合的简写形式

表单中的双向绑定

因为没有任何原生 HTML 元素遵循了 x 值和 xChange 事件的命名模式,所以与表单元素进行双向绑定需要使用 NgModel

基本使用

根据之前基本的双向绑定知识,[(ngModel)]语法可拆解为:

  • 名为ngModel的输入属性
  • 名为ngModelChange的输出属性

使用[(ngModule)]双向绑定的前提条件是在模块中引入FormsModule

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

@Component({
  selector: 'example-app',
  template: `
    
    
    

Value: {{ name }}

Valid: {{ ctrl.valid }}

`, }) export class SimpleNgModelComp { name: string = ''; setValue() { this.name = 'Nancy'; } }

上面这行代码相当于:

在表单中的使用

表单中使用[(ngModel)],需要做下面两件事的其中之一

  • 给控件加上name属性
  • 将ngModelOptions.standalone设为true

注意:表单中使用双向数据绑定,知识点比较多,这里只做简单了解,后续会出专门章节探讨

内置指令

循环指令 *ngFor (非常基础,掌握)

arr:string[] = ['张三','李四','王五']; 
trackByItems(index: number, item: Item): number { return item.id; }

索引值:{{i}} -- 内容:{{item}}
//trackBy一般和长列表一起使用,减少dom替换次数,提升性能
({{item.id}}) {{item.name}}

条件渲染 *ngIf ngStyle  ngClass  ngSwitch(非常基础)

isShow: Boolean = true;
personState: number = 2;

//频繁切换不建议用,频繁加载和移除有较高的性能消耗 (重要)

命令模式

// 不频繁切换推荐用

命令模式

// 频繁切换推荐用 currentStyles = { 'font-style': this.canSave ? 'italic' : 'normal', 'font-weight': !this.isUnchanged ? 'bold' : 'normal', 'font-size': this.isSpecial ? '24px' : '12px' };
ngClass
ngStyle
// 使用样式有2种(style.dispaly 和 class.hidden)

style模式

//频繁切换建议用样式

class模式

//匹配多种情况的条件渲染,跟vue的v-if/v-else-if/v-else类似 //适合多种状态,显示一种的情况
工作
吃饭
睡觉

双向数据绑定指令 [(ngModel)]

//Angular不能直接识别ngModel,需要通过引入模块FormsModule来访问
import {FormsModule} from '@angular/forms';
imports: [FormsModule]

public name = "张三";
 //人工绑定,更好的做法是通过响应式表单绑定
 //备选

//属性绑定+事件绑定 = ngModel (重要)

模板引用变量

基本使用

使用井号(#)声明模板引用变量,可以获取DOM 元素、指令、组件、TemplateRef 或 Web Component。

import {Component} from '@angular/core';
@Component({
  selector: 'app-tpl-var',
  template: `
    
    
  `,
})
export class TplVarComponent {
  constructor() { }
  callPhone(value: string) {
    console.log('callPhone', value);
  }
}

ref

还有种写法就是ref, 下面两种写法是一样的



引用组件

在组件章节,介绍了获取子组件的属性和方法,有两种方法:本地变量和@viewChild()

import {Component} from '@angular/core';
@Component({
  selector: 'app-tpl-var',
  template: `
    
size: {{ size }}
`, }) export class TplVarComponent { size = 16; constructor() { } }

输入和输出

输入属性

子组件

import { Component, Input } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `

Today's item: {{item}}

` }) export class ItemDetailComponent { @Input() item: string; }

父组件

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
     
  `,
})
export class AppComponent {
  currentItem = 'Television';
}

输出属性

子组件

import { Component, Output, EventEmitter } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
             `,
})
export class ItemOutputComponent {
  @Output() newItemEvent = new EventEmitter();
  addNewItem(value: string) {
    this.newItemEvent.emit(value);
  }
}

父组件

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
     
  `,
})
export class AppComponent {
   items = ['item1', 'item2', 'item3', 'item4'];
    addItem(newItem: string) {
      this.items.push(newItem);
    }
}

在元数据中声明输入和输出属性

固然可以在 @Directive 和 @Component 元数据中声明 inputs 和 outputs, 不推荐提供别名。

@Input()和@Output()可以接收一个参数,作为变量的别名,那么父组件中只能用别名绑定 子组件

import { Component, Input, EventEmitter, Output } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `

Today's item: {{item}}

` }) export class ItemDetailComponent { @Input('aliasItem') item: string; // decorate the property with @Input() @Output('newItem') newItemEvent = new EventEmitter(); addNewItem(value: string) { this.newItemEvent.emit(value); } }

父组件

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
     
  `,
})
export class AppComponent {
  currentItem = 'Television';
  items = ['item1', 'item2', 'item3', 'item4'];
  addItem(newItem: string) {
    this.items.push(newItem);
  }
}

输入属性一定要用中括号[]绑定?

如果绑定的值是静态的,就不需要[]

import { Component } from '@angular/core';
@Component({
  selector: 'app-root',
  template: `
     
  `,
})
export class AppComponent {
  // currentItem = 'Television';
}

管道(基础,掌握)

常用的管道

1、大小写字母转换

str = 'Hello';
str1 = 'World';

{{str | uppercase}}-{{str1 | lowercase}}

//str:hello str1:WORLD

2、 日期格式化(经常使用)

today = new Date();

现在的时间是{{today | date:'yyyy-MM-dd HH:mm:ss'}}

3、保留小数后面多少位 下面例子的含义是,3表示最少几位整数,后面的2-4表示最少最少2位小数,最多4位小数,不足补零,小数会四舍五入。

num = 125.156896;

num保留4位小数的值是:{{num | number:'3.2-4'}}

//125.1569

4、货币转换

count = 5;
price = 1.5;

数量:{{count}}

// 数据:5

价格:{{price}}

// 价格:1.5

总价:{{(price * count) | currency:'¥'}}

// 价格:¥7.5

5、字符串截取

name = '只对你说';

{{name | slice : 2 : 4}}

// 你说

6、json格式化(有时需要看一下数据)

 

{{ { name: 'semlinker' } | json }}

// { "name": "semlinker" }

自定义管道

1、创建管道文件

ng g pipe /piper/mypiper

2、在管道文件中写自己的逻辑transform两个参数分别表示传入值和参数

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'multiple'
})
export class MypiperPipe implements PipeTransform {
  transform(value: any, args?: any): any {
    //value:输入值 args:参数
    if(!args){//无参的情况下
      args = 1;
    }
    return value*args;
  }
}

注意:通过命令行生成的管道(过滤器),会自动在全局声明; 管道传入的参数是在':'冒号后面表示

更多编程相关知识,请访问:编程视频!!

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

412

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

533

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

310

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

75

2025.09.10

html版权符号
html版权符号

html版权符号是“©”,可以在html源文件中直接输入或者从word中复制粘贴过来,php中文网还为大家带来html的相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

616

2023.06.14

html在线编辑器
html在线编辑器

html在线编辑器是用于在线编辑的工具,编辑的内容是基于HTML的文档。它经常被应用于留言板留言、论坛发贴、Blog编写日志或等需要用户输入普通HTML的地方,是Web应用的常用模块之一。php中文网为大家带来了html在线编辑器的相关教程、以及相关文章等内容,供大家免费下载使用。

655

2023.06.21

html网页制作
html网页制作

html网页制作是指使用超文本标记语言来设计和创建网页的过程,html是一种标记语言,它使用标记来描述文档结构和语义,并定义了网页中的各种元素和内容的呈现方式。本专题为大家提供html网页制作的相关的文章、下载、课程内容,供大家免费下载体验。

470

2023.07.31

html空格
html空格

html空格是一种用于在网页中添加间隔和对齐文本的特殊字符,被用于在网页中插入额外的空间,以改变元素之间的排列和对齐方式。本专题为大家提供html空格的相关的文章、下载、课程内容,供大家免费下载体验。

245

2023.08.01

PS使用蒙版相关教程
PS使用蒙版相关教程

本专题整合了ps使用蒙版相关教程,阅读专题下面的文章了解更多详细内容。

23

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Vue.js:纪录片
Vue.js:纪录片

共1课时 | 0.2万人学习

Angular js入门篇
Angular js入门篇

共17课时 | 3.5万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号