搜索
首页web前端js教程聊聊angular10中模板如何进行数据绑定?

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

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

绑定语法概览

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

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

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

<!-- model => view -->
{{expression}}
[target]="expression"
bind-target="expression"

<p> {{ msg }} </p>  // 插值表达式
<img [src]="heroImageUrl"> // 属性绑定
<app-hero-detail [hero]="currentHero"></app-hero-detail> // 组件通过属性绑定的方式传参
<div [ngClass]="{&#39;special&#39;: isSpecial}"></div> // 样式绑定
<div [class.special]="isSpecial">Special</div> // class绑定
<button [style.color]="isSpecial ? &#39;red&#39; : &#39;green&#39;"> // style绑定
<button [attr.aria-label]="help">help</button> // Attribute绑定

<!-- view  => model -->
(target)="statement"
on-target="statement"

<button (click)="onSave()">Save</button> // 元素事件
<app-hero-detail (deleteRequest)="deleteHero()"></app-hero-detail> // 组件事件,用于监听子组件传递过来的参数
<div (myClick)="clicked=$event" clickable>click me</div> // 指令事件

<!-- view <=> model -->
[(target)]="expression"
bindon-target="expression"

<input [(ngModel)]="name"> // 双向数据绑定

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 type="text" value="Sarah">

当浏览器渲染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,因此该按钮就被禁用了。

<button disabled>Test Button</button>

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

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

<input [disabled]="condition ? true : false">
<input [attr.disabled]="condition ? &#39;disabled&#39; : null">

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

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

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

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
      <p>变量绑定:{{ title }}</p>
      <p>方法绑定:{{ getVal }}</p>
      <p>方法绑定:{{ getVal2() }}</p>
      <p>简单运算 {{ 1 + 1 }}.</p>
      <p>简单运算 {{ price * 0.7 }}.</p>
      <p>简单运算:{{ gender === 0 ? &#39;男&#39;:&#39;女&#39; }}</p>
      <p>与方法结合 {{ price * 0.7 + getVal }}.</p>
      <p>与方法结合 {{ price * 0.7 + getVal2() }}.</p>
  `,
})
export class AppComponent {
  title = "模板绑定";
  price = 30;
  gender = 0;
  get getVal(): number { //es6新语法,函数可以当做变量来使用
    return 20;
  }
  getVal2(): number {
    return 33;
  }
}

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

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

属性绑定(基础,掌握)

绑定图片

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
    <img src="../assets/images/madao.jpg" alt="madao" />
    <img [src]="madaoSrc" alt="madao" /> // 推荐
    <img bind-src="madaoSrc" alt="madao" />
    `,
  styles: []
})
export class AppComponent {
  madaoSrc = &#39;../assets/images/madao.jpg&#39;;
}

绑定普通属性

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
    <img [src]="user.pic" [alt]="user.name" />
    <table class="table-bordered">
      <tr>
        <th>name</th>
        <th>phone</th>
        <th>age</th>
      </tr>
      <tr>
        <td>张三</td>
        <td>13398490594</td>
        <td>33</td>
      </tr>
      <tr>
        <td [colSpan]="colSpan">李四</td> // 注意colSpan和colspan
        <td>15079049984</td>
        <td>22</td>
      </tr>
    </table>
    <button class="btn btn-primary" [disabled]="isDisabled">click</button>
    `,
  styles: []
})
export class AppComponent {
  madaoSrc = &#39;../assets/images/madao.jpg&#39;;
  user = {
   name: &#39;madao&#39;,
   pic: this.madaoSrc
  };
  colSpan = 2;
  isDisabled = false;
}

绑定自定义属性

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

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

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

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
    <img src="{{ user.pic }}" alt="{{ user.name }}" />
    `,
  styles: []
})
export class AppComponent {
  madaoSrc = &#39;../assets/images/madao.jpg&#39;;
  user = {
    name: &#39;madao&#39;,
    pic: this.madaoSrc
  };
}

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

绑定单个样式

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
      <button type="button" class="btn" [class.btn-primary]="theme === &#39;primary&#39;">Primary</button>
      <button type="button" class="btn" [class.btn-secondary]="true">secondary</button>
      <button type="button" class="btn" [class.btn-success]="isSuccess">success</button>
      <button type="button" class="btn" [class.btn-danger]="&#39;啦啦啦&#39;">danger</button>
      <button type="button" class="btn" [class.btn-danger]="0">danger</button>   //false
      <button type="button" class="btn" [class.btn-danger]="undefined">danger</button>  //false
    `,
  styles: []
})
export class AppComponent {
    theme = &#39;primary&#39;;
    isSuccess = true;
}

绑定多个class

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
      <button type="button" [class]="btnCls">btnCls</button>
      <button type="button" [class]="btnCls2">btnCls2</button>
      <button type="button" [class]="btnCls3">btnCls3</button>

      <!-- 也可以用内置指令ngClass -->
      <button type="button" [ngClass]="btnCls">btnCls</button>
      <button type="button" [ngClass]="btnCls2">btnCls2</button>
      <button type="button" [ngClass]="btnCls3">btnCls3</button>
    `,
  styles: []
})
export class AppComponent {
    btnCls = &#39;btn btn-primary&#39;;
    btnCls2 = [&#39;btn&#39;, &#39;btn-success&#39;];
    btnCls3 = {
      btn: true,
      &#39;btn-info&#39;: true
    };
}

绑定单个style

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
      <p [style.color]="&#39;#f60&#39;">一段文字</p>
      <p [style.height]="&#39;50px&#39;" [style.border]="&#39;1px solid&#39;">设置高度</p>
      <p [style.height.px]="50" [style.border]="&#39;1px solid&#39;">设置高度</p>
    `,
  styles: []
})
export class AppComponent {}

绑定多个style

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
      <p [style]="style1">style1</p>
      <p [style]="style2">style2</p>
      <p [style]="style3">style3</p>
      <!-- 也可以用内置指令ngStyle, 但不推荐,以后可能会弃用 -->
      <!--  <p [ngStyle]="style1">style1</p>-->
      <!--  <p [ngStyle]="style2">style2</p>-->

      <!-- ngStyle只接收对象 -->
      <p [ngStyle]="style3">style3</p>
    `,
  styles: []
})
export class AppComponent {
  style1 = &#39;width: 200px;height: 50px;text-align: center;border: 1px solid;&#39;;
  style2 = [&#39;width&#39;, &#39;200px&#39;, &#39;height&#39;, &#39;50px&#39;, &#39;text-align&#39;, &#39;center&#39;, &#39;border&#39;, &#39;1px solid&#39;]; // 有问题
  style3 = {
    width: &#39;200px&#39;,
    height: &#39;50px&#39;,
    &#39;text-align&#39;: &#39;center&#39;,
    border: &#39;1px solid&#39;
  };
}

绑定优先级

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

事件绑定(基础,掌握)

基本用法

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
      <button type="button" class="btn btn-primary" (click)="onClick()">Primary</button>
    `,
  styles: []
})
export class AppComponent {
    onClick() {
      console.log(&#39;onClick&#39;);
    } 
}

事件对象

$event 就是原生的事件对象

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
      <button type="button" class="btn btn-primary" (click)="onClick($event)">Primary</button>
    `,
  styles: []
})
export class AppComponent {
    onClick(event: MouseEvent) {
      console.log(&#39;onClick&#39;, event.target);
      //直接用event.target.value会报错,要用类型断言
      console.log((event.target as HTMLInputElement).value)
    }
}

事件捕获或事件冒泡

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
      <div style="width:200px;height:200px;background-color:red;" (click)="parentClick()">
      <!--<div style="width:100px;height:100px;background-color:blue;" (click)="chilrenClick($event)"></div>-->
      <div style="width:100px;height:100px;background-color:blue;" (click)="$event.stopPropagation()"></div> //可以在html使用一些简单的语法
    </div>
    `,
  styles: []
})
export class AppComponent {
  parentClick() {
    console.log(&#39;parentClick&#39;);
  }
  chilrenClick(event: MouseEvent) {
    event.stopPropagation();  //阻止事件冒泡
    console.log(&#39;chilrenClick&#39;);
  }
}

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

输入属性

子组件

import { Component, Input } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `<p>
               Today&#39;s item: {{item}}
             </p>`
})
export class ItemDetailComponent  {
  @Input() item: string;
}

父组件

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
     <app-item-detail [item]="currentItem"></app-item-detail>
  `,
})
export class AppComponent {
  currentItem = &#39;Television&#39;;
}

输出属性

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

子组件

import { Component, Output, EventEmitter } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `<label>Add an item: <input #newItem></label>
             <button (click)="addNewItem(newItem.value)">Add to parent&#39;s list</button>`,
})
export class ItemOutputComponent {
  @Output() newItemEvent = new EventEmitter<string>(); //子传父,输出属性
  addNewItem(value: string) {
    this.newItemEvent.emit(value); //自定义事件触发
  }
}

父组件

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
     <app-item-output (newItemEvent)="addItem($event)"></app-item-output> //监听自定义事件
  `,
})
export class AppComponent {
   items = [&#39;item1&#39;, &#39;item2&#39;, &#39;item3&#39;, &#39;item4&#39;];
    addItem(newItem: string) {
      this.items.push(newItem);
    }
}

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

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

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

子组件

import { Component, Input, EventEmitter, Output } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `<p>
               Today&#39;s item: {{item}}
             </p>`
})
export class ItemDetailComponent  {
  @Input(&#39;aliasItem&#39;) item: string; 
  @Output(&#39;newItem&#39;) newItemEvent = new EventEmitter<string>();
  
  addNewItem(value: string) {
     this.newItemEvent.emit(value);
   }
}

父组件

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
     <app-item-detail [aliasItem]="currentItem" //注意是绑定的别名
     (newItem)="addItem($event)"></app-item-detail> //注意是监听的别名
  `,
})
export class AppComponent {
  currentItem = &#39;Television&#39;;
  items = [&#39;item1&#39;, &#39;item2&#39;, &#39;item3&#39;, &#39;item4&#39;];
  addItem(newItem: string) {
    this.items.push(newItem);
  }
}

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

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

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
     <app-item-detail item="static item"></app-item-detail>
  `,
})
export class AppComponent {
  // currentItem = &#39;Television&#39;;
}

双向绑定(基础,掌握)

先决条件

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

基本的双向绑定

子组件

import {Component, OnInit, ChangeDetectionStrategy, EventEmitter, Input, Output} from &#39;@angular/core&#39;;@Component({  selector: &#39;app-sizer&#39;,  template: `
    <div>
      <button class="btn btn-danger" (click)="dec()" title="smaller">-</button>
      <button class="btn btn-primary" (click)="inc()" title="bigger">+</button>
      <label [style.font-size.px]="size">FontSize: {{size}}px</label>
    </div>
  `,  styles: [
  ],  changeDetection: ChangeDetectionStrategy.OnPush
})export class SizerComponent implements OnInit {  @Input()  size: number | string;  
  // 想要用双向绑定语法,output变量名就一定是输入属性名加上Change  @Output() sizeChange = new EventEmitter<number>();  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 &#39;@angular/core&#39;;@Component({  selector: &#39;app-root&#39;,  template: `
     <app-sizer [(size)]="fontSizePx"></app-sizer>
     <div [style.font-size.px]="fontSizePx">Resizable Text</div>
  `,
})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 值的事件。

简写形式

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

<app-sizer [size]="fontSizePx" (sizeChange)="fontSizePx=$event"></app-sizer>

表单中的双向绑定

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

基本使用

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

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

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

import {Component} from &#39;@angular/core&#39;;

@Component({
  selector: &#39;example-app&#39;,
  template: `
    <input [(ngModel)]="name" #ctrl="ngModel" required>
    
    <p>Value: {{ name }}</p>
    <p>Valid: {{ ctrl.valid }}</p>
    
    <button (click)="setValue()">Set value</button>
  `,
})
export class SimpleNgModelComp {
  name: string = &#39;&#39;;

  setValue() {
    this.name = &#39;Nancy&#39;;
  }
}
<input [(ngModel)]="name" />
上面这行代码相当于:
<input [value]="name" (input)="name = $event.target.value" />

在表单中的使用

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

  • 给控件加上name属性
  • 将ngModelOptions.standalone设为true
<form>
    <input [(ngModel)]="value" name="name" />
    <input [(ngModel)]="value" [ngModelOptions]="{ standalone: true }" />
</form>

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

内置指令

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

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

<div *ngFor="let item of arr; let i=index" (click)=&#39;choseThis(item,i)&#39;>
   索引值:{{i}} -- 内容:{{item}}
</div>

//trackBy一般和长列表一起使用,减少dom替换次数,提升性能
<div *ngFor="let item of items; trackBy: trackByItems">
  ({{item.id}}) {{item.name}}
</div>

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

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

//频繁切换不建议用,频繁加载和移除有较高的性能消耗 (重要)
<p *ngIf="isShow">命令模式</p> // 不频繁切换推荐用
<p [hidden]="isShow">命令模式</p> // 频繁切换推荐用


currentStyles = {
      &#39;font-style&#39;:  this.canSave      ? &#39;italic&#39; : &#39;normal&#39;,
      &#39;font-weight&#39;: !this.isUnchanged ? &#39;bold&#39;   : &#39;normal&#39;,
      &#39;font-size&#39;:   this.isSpecial    ? &#39;24px&#39;   : &#39;12px&#39;
};
<div [ngClass]="isSpecial ? &#39;special&#39; : &#39;&#39;">ngClass</div>
<div [ngStyle]="currentStyles">
  ngStyle
</div>

// 使用样式有2种(style.dispaly 和 class.hidden)
<p [style.display]="isShow?&#39;block&#39;:&#39;none&#39;">style模式</p> //频繁切换建议用样式
<p [class.hidden]="isShow">class模式</p>


//匹配多种情况的条件渲染,跟vue的v-if/v-else-if/v-else类似
//适合多种状态,显示一种的情况
<div [ngSwitch] = &#39;personState&#39;>
    <div *ngSwitchCase="1">工作</div>
    <div *ngSwitchCase="2">吃饭</div>
    <div *ngSwitchDefault>睡觉</div>
</div>

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

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

public name = "张三";
<input [(ngModel)] = "name" type="text"> //人工绑定,更好的做法是通过响应式表单绑定
<input bindon-change="name" type="text"> //备选

//属性绑定+事件绑定 = ngModel (重要)
<input [value]="name" (input)="name=$event.target.value" >

模板引用变量

基本使用

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

import {Component} from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-tpl-var&#39;,
  template: `
    <input #phone placeholder="phone number" />
    <button (click)="callPhone(phone.value)">Call</button>
  `,
})
export class TplVarComponent {
  constructor() { }
  callPhone(value: string) {
    console.log(&#39;callPhone&#39;, value);
  }
}

ref

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

<input #fax placeholder="fax number" />

<input ref-fax placeholder="fax number" />

引用组件

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

import {Component} from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-tpl-var&#39;,
  template: `
    <div class="demo-sec">
      <button class="btn btn-primary" (click)="sizer.inc()">app inc</button>
      <app-sizer [(size)]="size" #sizer></app-sizer>
      size: {{ size }}
    </div>
  `,
})
export class TplVarComponent {
  size = 16;
  constructor() { }
}

输入和输出

输入属性

子组件

import { Component, Input } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `<p>
               Today&#39;s item: {{item}}
             </p>`
})
export class ItemDetailComponent  {
  @Input() item: string;
}

父组件

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
     <app-item-detail [item]="currentItem"></app-item-detail>
  `,
})
export class AppComponent {
  currentItem = &#39;Television&#39;;
}

输出属性

子组件

import { Component, Output, EventEmitter } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `<label>Add an item: <input #newItem></label>
             <button (click)="addNewItem(newItem.value)">Add to parent&#39;s list</button>`,
})
export class ItemOutputComponent {
  @Output() newItemEvent = new EventEmitter<string>();
  addNewItem(value: string) {
    this.newItemEvent.emit(value);
  }
}

父组件

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
     <app-item-output (newItemEvent)="addItem($event)"></app-item-output>
  `,
})
export class AppComponent {
   items = [&#39;item1&#39;, &#39;item2&#39;, &#39;item3&#39;, &#39;item4&#39;];
    addItem(newItem: string) {
      this.items.push(newItem);
    }
}

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

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

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

import { Component, Input, EventEmitter, Output } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `<p>
               Today&#39;s item: {{item}}
             </p>`
})
export class ItemDetailComponent  {
  @Input(&#39;aliasItem&#39;) item: string; // decorate the property with @Input()
  @Output(&#39;newItem&#39;) newItemEvent = new EventEmitter<string>();
  addNewItem(value: string) {
     this.newItemEvent.emit(value);
   }
}

父组件

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
     <app-item-detail [aliasItem]="currentItem" (newItem)="addItem($event)"></app-item-detail>
  `,
})
export class AppComponent {
  currentItem = &#39;Television&#39;;
  items = [&#39;item1&#39;, &#39;item2&#39;, &#39;item3&#39;, &#39;item4&#39;];
  addItem(newItem: string) {
    this.items.push(newItem);
  }
}

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

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

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-root&#39;,
  template: `
     <app-item-detail item="static item"></app-item-detail>
  `,
})
export class AppComponent {
  // currentItem = &#39;Television&#39;;
}

管道(基础,掌握)

常用的管道

1、大小写字母转换

str = &#39;Hello&#39;;
str1 = &#39;World&#39;;
<p>{{str | uppercase}}-{{str1 | lowercase}} </p>  //str:hello str1:WORLD

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

today = new Date();

<p>现在的时间是{{today | date:&#39;yyyy-MM-dd HH:mm:ss&#39;}}</p>

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

num = 125.156896;

<p>num保留4位小数的值是:{{num | number:&#39;3.2-4&#39;}}</p> //125.1569

4、货币转换

count = 5;
price = 1.5;

<p>数量:{{count}}</p> // 数据:5
<p>价格:{{price}}</p> // 价格:1.5
<p>总价:{{(price * count) | currency:&#39;¥&#39;}}</p> // 价格:¥7.5

5、字符串截取

name = &#39;只对你说&#39;;

<p>{{name | slice : 2 : 4}}</p> // 你说

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

 <p>{{ { name: &#39;semlinker&#39; } | json }}</p> // { "name": "semlinker" }

自定义管道

1、创建管道文件

ng g pipe /piper/mypiper

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

import { Pipe, PipeTransform } from &#39;@angular/core&#39;;

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

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

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

以上是聊聊angular10中模板如何进行数据绑定?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:掘金社区。如有侵权,请联系admin@php.cn删除
JavaScript的角色:使网络交互和动态JavaScript的角色:使网络交互和动态Apr 24, 2025 am 12:12 AM

JavaScript是现代网站的核心,因为它增强了网页的交互性和动态性。1)它允许在不刷新页面的情况下改变内容,2)通过DOMAPI操作网页,3)支持复杂的交互效果如动画和拖放,4)优化性能和最佳实践提高用户体验。

C和JavaScript:连接解释C和JavaScript:连接解释Apr 23, 2025 am 12:07 AM

C 和JavaScript通过WebAssembly实现互操作性。1)C 代码编译成WebAssembly模块,引入到JavaScript环境中,增强计算能力。2)在游戏开发中,C 处理物理引擎和图形渲染,JavaScript负责游戏逻辑和用户界面。

从网站到应用程序:JavaScript的不同应用从网站到应用程序:JavaScript的不同应用Apr 22, 2025 am 12:02 AM

JavaScript在网站、移动应用、桌面应用和服务器端编程中均有广泛应用。1)在网站开发中,JavaScript与HTML、CSS一起操作DOM,实现动态效果,并支持如jQuery、React等框架。2)通过ReactNative和Ionic,JavaScript用于开发跨平台移动应用。3)Electron框架使JavaScript能构建桌面应用。4)Node.js让JavaScript在服务器端运行,支持高并发请求。

Python vs. JavaScript:比较用例和应用程序Python vs. JavaScript:比较用例和应用程序Apr 21, 2025 am 12:01 AM

Python更适合数据科学和自动化,JavaScript更适合前端和全栈开发。1.Python在数据科学和机器学习中表现出色,使用NumPy、Pandas等库进行数据处理和建模。2.Python在自动化和脚本编写方面简洁高效。3.JavaScript在前端开发中不可或缺,用于构建动态网页和单页面应用。4.JavaScript通过Node.js在后端开发中发挥作用,支持全栈开发。

C/C在JavaScript口译员和编译器中的作用C/C在JavaScript口译员和编译器中的作用Apr 20, 2025 am 12:01 AM

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。 1)C 用于解析JavaScript源码并生成抽象语法树。 2)C 负责生成和执行字节码。 3)C 实现JIT编译器,在运行时优化和编译热点代码,显着提高JavaScript的执行效率。

JavaScript在行动中:现实世界中的示例和项目JavaScript在行动中:现实世界中的示例和项目Apr 19, 2025 am 12:13 AM

JavaScript在现实世界中的应用包括前端和后端开发。1)通过构建TODO列表应用展示前端应用,涉及DOM操作和事件处理。2)通过Node.js和Express构建RESTfulAPI展示后端应用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web开发中的主要用途包括客户端交互、表单验证和异步通信。1)通过DOM操作实现动态内容更新和用户交互;2)在用户提交数据前进行客户端验证,提高用户体验;3)通过AJAX技术实现与服务器的无刷新通信。

了解JavaScript引擎:实施详细信息了解JavaScript引擎:实施详细信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎内部工作原理对开发者重要,因为它能帮助编写更高效的代码并理解性能瓶颈和优化策略。1)引擎的工作流程包括解析、编译和执行三个阶段;2)执行过程中,引擎会进行动态优化,如内联缓存和隐藏类;3)最佳实践包括避免全局变量、优化循环、使用const和let,以及避免过度使用闭包。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境