模板语法

By admin in 4858美高梅 on 2019年5月5日

Angular 5.x Template Syntax Learn Note

模板语法

作者们的 Angular 应用管理着用户之所见和所为,并因而 Component
类的实例(组件)和面向用户的模板来与用户交互。

从使用模型-视图-调节器 (MVC) 或模型-视图-视图模型 (MVVM)
的经历中,好些个开采人士都纯熟了组件和模板那三个概念。 在 Angular
中,组件扮演着调节器或视图模型的剧中人物,模板则扮演视图的剧中人物。

来探视写视图的模板都急需什么样。本章将覆盖模板语法中的下列基本要素:

  • <a href=”#html”>HTML</a>
  • <a href=”#inter”>插值表明式</a>
  • <a href=”#tmpex”>模板表达式</a>
  • <a href=”#tmpsm”>模板语句</a>
  • <a href=”#bind”>绑定语法</a>
  • <a href=”#prop”>属性绑定</a>
  • <a href=”#attr”>attribute、class和style绑定</a>
  • <a href=”#event”>事件绑定</a>
  • 模板语法。<a href=”#two”>双向数据绑定</a>
  • <a href=”#ngmodel”>使用 NgModel 进行双向数据绑定</a>
  • <a href=”#direct”>内置指令</a>
    • <a href=”#class”>NgClass</a>
    • <a href=”#style”>NgStyle</a>
    • <a href=”#if”>NgIf</a>
    • <a href=”#switch”>NgSwitch</a>
    • <a href=”#for”>NgFor</a>
  • <a href=”#star”>* 与<template></a>
  • <a href=”#var”>模板引用变量</a>
  • <a href=”#ipt”>输入输出属性</a>
  • <a href=”#opt”>模板表明式操作符</a>
    • <a href=”#pip”>管道</a>
    • <a href=”#safe”>安全导航操作符(?.)</a>

在线例子演示了本章中描述的有着语法和代码片段。

<h3 id=”html”>HTML</h3>

HTML 是 Angular 模板的言语。即刻运转选用的模板是纯 HTML 的:

<h1>
<a id="hello-angular" class="anchor" href="#hello-angular" aria-hidden="true"></a>Hello Angular</h1>

少了一些具有的 HTML
语法都以有效的模板语法。但值得注意的不等是<script>要素,它被剥夺了,以阻挡脚本注入攻击的高风险。(实际上,<script>只是被忽略了。)

些微合法的 HTML
被用在模板中是从未有过意义的。<html><body><base>要素那个舞台上中并不曾装扮有用的剧中人物。基本上全数其余的因素都如出一辙被接纳。

能够经过组件和指令来扩大模板中的 HTML
词汇。它们看起来正是新成分和质量。接下来将学习怎么样通过数量绑定来动态获取/设置
DOM(文档对象模型)的值。

数量绑定的第贰种样式 ——插值表明式—— 体现了模版的 HTML 能够有多丰富。

<h三 id=”inter”>插值表明式</h三>

在以前的 Angular
教程中,我们碰着过由双花括号{{}}括起来的插值表明式。

<p>My current hero is {{currentHero.firstName}}</p>

我们选取插值表明式把计算后的字符串插入到 HTML
成分标签内的文本或对标签的性子举办赋值。

<h3>
  {{title}}
  [站外图片上传中……(2)]
</h3>

在括号之间的“素材”,日常是组件属性的名字。Angular
会用组件中相应属性的字符串值,替换这几个名字。上例中,Angular
总结titleheroImageUrl品质的值,并把它们填在空白处。首先展现粗体的运用标题,然后呈现铁汉的图片。

相似的话,括号间的资料是八个模板表明式,Angular
先对它求值,再把它调换到字符串。下列插值表达式通过把括号中的四个数字相加表明了那或多或少:

<!-- "The sum of 1 + 1 is 2" -->
<p>The sum of 1 + 1 is {{1 + 1}}</p>

本条表明式能够调用宿主组件的章程,就像是上边用的getVal()

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

Angular
对具备双花括号中的表明式求值,把求值的结果转变来字符串,并把它们跟周边的字符串字面量连接起来。最终,把这一个组合出来的插值结果赋给要素或指令的特性

外表上看,我们在要素标签之间插入了结果和对标签的个性进行了赋值。这样考虑起来很方便,并且那一个误会很少给大家带来麻烦。但严俊来讲,那是非符合规律的。插值表达式是七个独特的语法,Angular
把它转变到了特性绑定,前边将会分解那或多或少。

授课属性绑定此前,先深切摸底一下模板表达式和模板语句。

<h三 id=”tmpex”>模板表明式</h三>

模板表达式发出3个值。Angular
推行这几个表明式,并把它赋值给绑定目标的个性,这么些绑定目标大概是 HTML
成分、组件或指令。

当我们写{{1 + 1}}时,是往插值表达式的括号中放进了3个模板表明式。在品质绑定中会再度察看模板表明式,它出现在=右侧的引号中,看起来像这样:[property]="expression"

编辑模板表明式所用的语言看起来很像 Dart。许多 Dart
表明式也是法定的沙盘表明式,但不是全体。

Dart 中那么些具有或或许引发副成效的表明式是被明确命令禁止的,包蕴:

  • 赋值 (=, +=, -=, …)
  • newconst
  • 使用;的链式表明式
  • 自增或自减操作符 (++--)

别的和 Dart 语法分明的不及包涵:

  • 不援助 Dart
    字符串插值;比如,必须使用"'the title is '+ title"而不是"'the title is $title'"
  • 不协助位运算符|&
  • 负有新的模板表明式运算符,举例|&

学习资料来自
Angular.cn 与
Angular.io。

Angular 5.x 模板语工学习笔记

标签(空格分隔): Angular

Note on
github.com


表达式上下文

只怕更令人吃惊的是,模板表明式不能引用静态属性。也无法引用拔尖变量或函数,比方从dart:html引入的windowdocument。不能够直接调用print或从dart:math导入的函数。它们被局限于只可以访问来自表明式上下文中的成员。

典型的表明式上下文便是这一个零件实例,它是各个绑定值的发源。

当见到包裹在双花括号中的 title ({{title}})
时,大家就知道title是其一数目绑定组件中的3个属性。当见到[disabled]="isUnchanged"中的
isUnchanged 时,大家就精通正在引用该零件的isUnchanged属性。

一般,组件自身正是表明式的上下文,那种情景下,模板表达式会引用那多少个组件。

表明式的上下文能够总结组件之外的对象。模板引用变量不畏计划的上下文对象之1。

模板语法

在线例子

在 Angular 中,组件扮演着调控器或视图模型的角色,模板则扮演视图的剧中人物。

上手

官网Heroes 例子:Demo On
Github。

表明式指南

模板表明式能实现或毁掉二个使用。请遵照下列指南:

  • 从没可知的副成效
  • 试行高效
  • 相当轻松
  • 幂等性

胜出上边指南外的情形相应只出以后那多少个你确信自身曾经到头领略的一定情景中。

模板中的 HTML

HTML 是 Angular 模板的语言。

<h1>Hello Angular</h1>

为幸免脚本注入攻击的危机,<script>
成分被剥夺了(忽略了)。更加多内容参见安全。

<html><body><base> 成分在此并未有行使的含义。

一、模板与数码绑定

未曾可见的副效能

模板表明式除了目的属性的值以外,不应当退换使用的别样意况。

那条规则是 Angular
“单向数据流”攻略的基础。永恒不要顾忌读取组件值可能更动其它的彰显值。在三次独自的渲染进度中,视图应该总是牢固的。

插值表明式 (Interpolation) {{...}}

插值表达式能够把总括后的字符串插入到 HTML
成分标签内的公文或对标签的性质实行赋值。

一般的话,括号间的资料是四个模板表达式,Angular
先对它求值,再把它调换到字符串。

<!-- "The sum of 1 + 1 is 2" -->
<p>The sum of 1 + 1 is {{1 + 1}}</p>

一. 来得数据

  1. selector 采用自定义标签的名号。

  2. template 属性定义内联模板;templateUrl 属性定义外链模板。

  3. 值的扬言和发轫化。

    export class AppComponent {
        // 变量赋值的方式初始化组件
        // title = 'Tour of Heroes';
        // myHero = 'Vencent';
        title: string;
        myHero: string;
        Heroes = ['Windstorm', 'Vencent', 'Bombasto', 'Magneta', 'Tornado',];
    
        // 构造函数来声明和初始化属性
        constructor() {
          this.title = 'Tour of Heroes';
          this.myHero = this.Heroes[1];
        }
    }
    
  4. {{ [data] }}插值表达式 (interpolation) ,模板绑定属性;
    *ngFor="let [item] of [list]"模板循环,ngFor
    可感到任何可迭代的
    (iterable) 目的重复渲染条约;
    ngIf
    指令会依赖八个布尔条件来展现或移除1个成分,*ngIf="[condition]"。具体参见下一节(模板语法)。

  5. 实体类的扬言。

    export class Hero {
       constructor(
       public id: number,
       public name: string) { }
    }
    

    public id: number,

    参数作为质量的简写语法:

    • 宣称了一个构造函数参数及其类型
    • 扬言了一个同名的集体属性
    • new出该类的三个实例时,把该属性开端化为响应的参数值
实施高效

Angular
推行模板表达式比大家想像的数次。它们或然在每趟开关或鼠标移动后被调用。表达式应该异常的快甘休,不然用户就能够以为拖沓,特别是在异常的慢的装置上。当计算代价较高时,应该思索缓存那多少个从任何值总计得出的值。

模板表明式 (Template expressions)

模板表明式产生1个值。Angular
实行这么些表明式,并把它赋值给绑定目的的性质,那一个绑定目标或者是 HTML
成分、组件或指令。

模板表明式不支持的内容蕴含:

  • 赋值 (=, +=, -=, …)
  • new 运算符
  • 使用 ;, 的链式表明式
  • 自增或自减操作符 (++--)
  • 不协理位运算 |&
  • 装有新的模版表明式运算符,举个例子 |?.
  • 不能够引用全局命名空间中的任何事物。 不能够引用 window
    document。不可能调用 console.logMath.max

二. 模板语法

  1. HTML是Angular模板的言语
    HTML是Angular模板的言语;<script>要素,它被剥夺(忽略)了,以阻挠脚本注入攻击的高风险:安全。

  2. 插值表明式

    {{...}}

    // 作为文本
    <!-- "The sum of 1 + 1 is 2" -->
    <p>The sum of 1 + 1 is {{1 + 1}}</p>
    
    // 作为属性值 image = img,由于此md编辑器会吞掉img标签
    <image src="{{heroImageUrl}}" style="height:30px">
    
  3. 模板表达式

    JavaScript 中那多少个具备或大概引发副效率的表明式是被取缔的:

    • 赋值(=+=-=,…)
    • new运算符
    • 使用;,的链式表明式
    • 自增或自减操作符(++--
    • 不协助位运算|&
    • 抱有新的模板表达式运算符,比如|?.!

    3.1 表达式上下文

    典型的表达式上下文正是这些组件实例,它是各个绑定值的来源于。
    表达式中的上下文变量是由模板变量命令的上下文变量(纵然有)零件的成员叠加而成的。
    假使大家要引用的变量名存在于2个以上的命名空间中,那么,模板变量是最优先的,其次是命令的上下文变量,最后是组件的积极分子

  4. 模板语句

    模板语句用来响应由绑定目的(如 HTML 成分、组件或指令)触发的轩然大波。

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

    模板语句解析器帮助中央赋值 (=) 和表明式链 (;,)。
    模板语句禁止以下:

    • new运算符
    • 自增或自减操作符(++--
    • 操作并赋值(+=-=,…)
    • 位操作符|&
    • 模板表达式运算符,比如|?.!

    四.1 语句上下文

    卓越的言语上下文就是方今组件的实例。
    <button (click)="onSave($event)">Save</button> <button *ngFor="let hero of heroes" (click)="deleteHero(hero)">{{hero.name}}</button> <form #heroForm (ngSubmit)="onSubmit(heroForm)"> ... </form>
    模板上下文中的变量名的事先级高于组件上下文中的变量名。在上边的deleteHero(hero)中,hero是多少个模板输入变量,而不是组件中的hero属性。

    模板语句无法引用全局命名空间的任刘亚辉西。比如不可能引用window
    document,也无法调用console.logMath.max

  5. 绑定语法

    数据方向 语法 绑定类型
    单向
    从数据源
    到视图目标
    {{expression}}
    [target]="expression"
    bind-target="expression"
    插值表达式
    Property
    Attribute

    样式
    单向
    从视图目标
    到数据源
    (target)="statement"
    on-target="statement"
    事件
    双向 [(target)]="expression"
    bindon-target="expression"
    双向
    • HTML attribute value 内定了开始值;DOM value property
      是当前值。
    • 模板绑定是通过 property 和事件来办事的,而不是 attribute
    • 插值表明式和总体性绑定只好设置属性,无法设置 attribute。
    • 在 Angular 的世界中,attribute
      唯壹的效果是用来起首化成分和指令的情状。

    如图 伍-一 所示,创立了一个 input
    成分,开端设置它的习性(Attribute)为 “Bob”,在获得它的 Attribute 和
    使用ng双向绑定值时,用户输入值(1二3)和 Attribute
    的值(Bob)是不一致的。
    4858美高梅 1

    五.一 属性绑定 ( [属性名] )

    • 单向输入

    • 绑定目的

      <img [src]="heroImageUrl">
      
    • 铲除副作用

      只绑定数据属性和这些只再次来到值而不做其余职业的点子。

    • 重回妥善的品种

      模板表达式应该回到目标属性所需项指标值。假使目标属性想要个数字,就回来数字。HeroDetail组件的hero属性想要1个Hero对象,那就在质量绑定中准确地给它三个Hero对象:
      <app-hero-detail [hero]="currentHero"></app-hero-detail>

    • 别忘了方括号

      方括号报告 Angular 要总括模板表明式。

    • 3回性字符串开首化

      • 目标属性接受字符串值。
      • 字符串是个固定值,能够直接统一到模块中。
      • 以此早先值永不改造。

      上边这一个例子把HeroDetailComponent的prefix属性初阶化为定位的字符串,而不是模板表明式。

      <app-hero-detail prefix="You are my" [hero]="currentHero"></app-hero-detail>
      
    • 属性绑定照旧插值表明式?

      <p>"{{titles}}" is the <i>interpolated</i> title.</p>
      <p>"" is the <i>property bound</i> title.</p>
      

      同情于插值表达式
      但数据类型不是字符串时,就务须利用质量绑定了,如图 ⑤-二 所示:
      4858美高梅 2

    • 剧情安全

      任由是插值表达式如故性质绑定,都不会允许带有 script 标签的 HTML
      泄漏到浏览器中。只渲染未有有剧毒的内容。比如上边包车型大巴绑定:

      <p [innerHTML]="scripts"></p>
      

      4858美高梅 3

    5.2 attribute、class 和
    style 绑定

    • attribute 绑定

      那是“绑定到目的属性
      (property)”那条规则中唯壹的两样。那是举世无双的能创设和装置
      attribute 的绑定格局。

      由attr前缀,八个点 (.) 和 attribute 的名字组成。
      把[attr.colspan]绑定到2个总计值:
      <table border="1"> <!-- 设置 colspan=2 --> <tr><td [attr.colspan]="1 + 1">1-2</td></tr> <tr><td>5</td><td>6</td></tr> </table>
      运作结果:

      4858美高梅 4

      attribute 绑定的首要用例之一是安装 ALX570IA
      attribute(译注:A奥迪Q7IA指可访问性,用于给生理残疾行动障碍者职员访问互连网提供有益):
      <!-- 创建和设置辅助技术的 ARIA 属性 --> <button [attr.aria-label]="actionName">{{actionName}} with Aria</button>

    • CSS 类绑定

      由class前缀,八个点 (.)和 CSS
      类的名字组成,[class.class-name]

      <!-- 使用绑定重置/覆盖所有类名 -->
      <div class="bad curly special" [class]="badCurly">Bad curly</div>
      

      4858美高梅 5
      能够绑定到特定的类名。

      <!-- 用属性打开/关闭“special”类 -->
      <div [class.special]="isSpecial">The class binding is special</div>
      <!-- 绑定`class.special`优先级高于class属性 -->
      <div class="special" [class.special]="!isSpecial">This one is not so special</div>
      

      4858美高梅 6

    • 体制绑定

      安装内联样式。由style前缀,贰个点 (.)和 CSS
      样式的质量名组成,[style.style-property]

      <button [style.color]="isSpecial ? 'red': 'green'">Red</button>
      

      有个别样式绑定中的样式带有单位:
      <button [style.font-size.em]="isSpecial ? 3 : 1" >Big</button> <button [style.font-size.%]="!isSpecial ? 150 : 50" >Small</button>

      4858美高梅 7

    5.三 事件绑定 ( (事件名)
    )

    事件绑定语法由等号左边带圆括号的对象事件动手引号中的模板语句组成。

    <button (click)="onSave()">Save</button>
    
    • $event
      和事件管理语句

      绑定会透过名字为$event的风云目的传递关于此事件的音信(包罗数据值)。

      <input [value]="currentHero.name"
             (input)="currentHero.name=$event.target.value">
      

      实行效果:
      4858美高梅 8

    • 应用 伊芙ntEmitter
      实现自定义事件

      一声令下使用 Angular
      EventEmitter
      来触发自定义事件。
      命令创制1个伊夫ntEmitter实例,并且把它看作品质暴揭露来。
      命令调用 EventEmitter.emit(payload)
      来触发事件,能够流传任王辉西作为音讯载荷。
      父指令通过绑定到那性情子来监听事件,并通过 $event
      对象来走访载荷。

    五.4 双向数据绑定 ( [(…)] )

    [(x)]语法结合了质量绑定的方括号[x]和事件绑定的圆括号(x)
    sizer.component.ts:

    import { Component, EventEmitter, Input, Output } from '@angular/core';
    @Component({
        selector: 'app-sizer',
        templateUrl: './sizer.component.html'
    })
    export class SizerComponent {
        @Input() size: number | string;
        @Output() sizeChange = new EventEmitter<number>();
    
        dec() { this.resize(-1); }
        inc() { this.resize(+1); }
    
        resize(delta: number) {
            console.log(delta, +this.size)
            this.size = Math.min(40, Math.max(8, +this.size + delta));
            console.log(this.size)
            this.sizeChange.emit(this.size);
        }
    }
    

    sizer.component.html:

    <div>
        <button (click)="dec()" title="smaller">-</button>
        <button (click)="inc()" title="bigger">+</button>
        <label [style.font-size.px]="size">FontSize: {{size}}px</label>
    </div>
    

    app.component.ts:
    <app-sizer [(size)]="fontSizePx"></app-sizer> <!-- 等价于下面的写法 --> <!-- <app-sizer [size]="fontSizePx" (sizeChange)="fontSizePx=$event"></app-sizer> --> <div [style.font-size.px]="fontSizePx">Resizable Text</div>

    app.component.ts:

    fontSizePx: number = 12;
    

    同时注目的在于 app.module.ts 引入 sizer.component.ts
    运营结果如图 伍-九 所示:
    4858美高梅 9

  6. 置于指令

    分为属性型指令结构型指令

    陆.一 常用内置属性型指令

    属性型指令会监听和退换其余HTML成分或机件的一举一动、成分属性(Attribute)、DOM属性(Property)。
    它们平时会作为HTML属性的名号而选拔在要素上。

    • NgClass – 增多或移除1组CSS类
    • NgStyle – 增加或移除壹组CSS样式
    • NgModel – 双向绑定到HTML表单成分
    • NgClass 指令

      能够而且加上或移除五个类。
      CSS
      类绑定
      是增进删减单个类的特等路线。
      而同时丰裕或移除七个 CSS 类,更加好的选项恐怕是NgClass

      // NgClass
      canSave: boolean     = true;
      isUnchanged: boolean = false;
      isSpecial: boolean   = true;
      currentClasses: {};
      setCurrentClasses() {
          this.currentClasses = {
              'saveable': this.canSave,
              'modified': !this.isUnchanged,
              'special': this.isSpecial
          }
      }
      ngOnInit(): void {
          // 初始化 currentClasses
          this.setCurrentClasses();
      }
      

      NgClass天性绑定到currentClasses,依照它来安装此因素的CSS类:

      <div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special</div>
      

      运转结果如图 陆-一所示:
      4858美高梅 10

    • NgStyle 指令

      NgStyle绑定能够同时设置四个内联样式。
      同样的,体制绑定也是安装单同样式值的简练方法。
      NgStyle是还要设置四个内联样式越来越好的取舍。
      // ngStyle currentStyles: {}; setCurrentStyles() { this.currentStyles = { 'font-style': this.canSave ? 'italic' : 'normal', 'font-weight': !this.isUnchanged ? 'bold' : 'normal', 'font-size': this.isSpecial ? '24px' : '12px' } }

      NgStyle属性绑定到currentStyles设置成分样式:

      <div [ngStyle]="currentStyles">
          This div is initially by ngStyle.
      </div>
      

      运转结果如图 6-二所示:
      4858美高梅 11

    • NgModel
      使用[(ngModel)]双向绑定到表单成分

      双向绑定表单成分。
      急需引进FormModule

      import { FormsModule } from '@angular/forms';
      
      @NgModule({
          imports: [
              FormsModule
          ]
      })
      export class AppModule { }
      

      ngModel可以经过事先的性质绑定和事件绑定达成:

      <input [value]="currentHero.name"
             (input)="currentHero.name=$event.target.value">
      

      ngModel的开始展览达成(自个儿的输入(ngModel)属性和输出(ngModelChange)属性):

      <input [ngModel]="currentHero.name"
             (ngModelChange)="currentHero.name=$event">
      

      ngModel的汇合落成格局是[(ngModel)]

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

      [(ngModel)]唯其如此设置数据绑定属性,假使有特意供给也得以拓展方式:

      app.component.html:

      <input [ngModel]="currentHero.name"
             (ngModelChange)="setUppercaseName($event)">
      

      app.component.ts:

      setUppercaseName(name) {
          this.currentHero.name = name.toUpperCase();
      }
      

      实践效力如下图(图 ⑥-三)所示:
      4858美高梅 12

    六.二 常用内置结构型指令

    结构型指令的职分是HTML布局。加多、移除和垄断(monopoly)DOM成分。
    留意指令前边的*号。

    • NgIf – 依照规则把2个要素增加到DOM中或从DOM移除
    • NgSwitch – 壹组在代表视图之间切换的一声令下
    • NgForOf – 对列表中的每一个条目重新套用一个模板
    • NgIf 指令

      和vue的v-if, v-show一样,分化于隐藏元素。
      ngIf可以严防空指针错误
      <div *ngIf="currentHero">Hello, {{ currentHero.name }}</div> <div *ngIf="nullHero">Hello, {{ nullHero.name }}</div>

    • NgFor 指令

      重复器指令。能够用在简约的成分上,也能够用在叁个零件成分上。
      赋值给*ngFor的文件是用于引导重复器怎样专门的工作的一声令下 –
      微语法(microsyntax)。
      <div *ngFor="let hero of heroes; let i = index">{{ i }} - {{hero.id + ': ' + hero.name }}</div>
      trackBy可防止止渲染全体条条框框。
      trackByHeroes(index: number, hero: Hero): number { return hero.id; }

      <div *ngFor="let hero of heroes; trackBy: trackByHeroes">
          ({{hero.id}}) {{hero.name}}
      </div>
      

      如图 6-4所示,假若未有trackBy,那一个按键都会接触完全的DOM成分交替;有了trackBy,则唯有修改了id的开关才会触发元素替换。

      4858美高梅 13

    • NgSwitch 指令

      能够从八个恐怕的要素中依照switch条件来展现某2个。包含多个互相合作指令:NgSwitchNgSwitchCaseNgSwitchDefault

      Pick ur favorite hero:
      <div class="favorite-hero">
          <label *ngFor="let hero of heroes">
              <input type="radio" name="hero" value="{{hero}}" (change)="selectHero(hero)"> {{hero.name}}
          </label>
      
          <div class="hero-desc" *ngIf="selectedHero" [ngSwitch]="selectedHero.id">
              <p *ngSwitchCase="1">Wow. U like {{ selectedHero.name }}, let's play!</p>
              <p *ngSwitchCase="2">Hey man, this is {{ selectedHero.name }}, fk u!</p>
              <p *ngSwitchCase="3">U like {{ selectedHero.name }}? R u sure?</p>
              <p *ngSwitchCase="4">Let's fk {{ selectedHero.name }}, go go go!</p>
              <p *ngSwitchDefault>Little {{ selectedHero.name }} is a cat.</p>
          </div>
      </div>
      
      selectedHero: Hero;
          selectHero(hero: Hero): void {
          this.selectedHero = hero;
      }
      

      运作效果如图 六-5 所示:

      4858美高梅 14

  7. 模板引用变量(#var)

    模板引用变量平时用来引用变量中的有个别DOM成分,它还足以引用Angular组件或指令或Web
    Component。
    接纳井号(#)来声称引用变量。#phone的情趣就是宣称一个名为phone的变量来引用<input>元素。
    深刻浅出来说,#[name]代表的是DOM成分,而在DOM其余地点能够直接调用这些name,取到的是DOM成分。

    举例上面包车型地铁事例:
    “`
    <input type=”text” #phone placeholder=”phone number”
    [(ngModel)]=”phoneNum”>

    <button type=”button” name=”button”
    (click)=”callPhone(phone.value)”>console.log phone
    “`

    phoneNum: string = '15342018244';
    callPhone(phone: string): void {
        console.log(phone);
    }
    

    运作效果如图 7-壹 所示。
    4858美高梅 15

    一声令下也足以修改那种表现,让那么些值引用到别处,举例它本身。
    NgForm一声令下就是如此做的。

    <form (ngSubmit)="onSubmit(heroForm)" #heroForm="ngForm">
    <!--  这里的heroForm实际上是一个Angular NgForm 指令的引用, 因此具备了跟踪表单中的每个控件的值和有效性的能力。 -->
        <div class="form-group">
            <label for="name">Name
                <input type="text" name="name" required [(ngModel)]="submitHero.name">
            </label>
        </div>
        <button type="submit" [disabled]="!heroForm.form.valid">Submit</button>
    </form>
    <div [hidden]="!heroForm.form.valid">
        {{submitMessage}}
    </div>
    
    submitHero: Hero = new Hero(null, '');
    submitMessage: string;
    onSubmit(hero): void {
        console.log(hero.form.value);
        this.submitMessage = 'success!';
    }
    

    运营作效果果如图 7-二 所示:

    4858美高梅 16

    可以用ref-前缀代替#

    <input ref-fax placeholder="number">
    <button (click)="callFax(fax.value)">BTN</button>
    
  8. 输入输出属性(@Input和@Output)

    具有组件皆为命令

    绑定目的
    等号左侧、绑定符:(), [],
    [()]中的属性/事件名、只可以绑定到体现标识为输入或输出属性。
    绑定源
    等号左侧、引号""或插值符号{{}}中的部分、源指令中的各样成员都会自行在绑定中可用。

    八.一 表明输入和输出属性

    对象属性必须被出示的符号为输入或输出。

    <app-hero-detail [hero]="currentHero" (deleteRequest)="deleteHero($event)">
    </app-hero-detail>
    

    src/app/hero-detail.component.ts:
    @Input() hero: Hero; @Output() deleteRequest = new EventEmitter<Hero>();

    还足以在指令元数据的inputsoutputs数组中标识处那一个分子。

    @Component({
        inputs: ['hero'],
        outputs: ['deleteRequest']
    });
    

    但是两者不能并且使用。

    八.贰 输入输出选用

    输入属性:接收数据值;
    输出属性:揭示时间生产者。
    输入和出口四个词是从目标指令角度说的。

    4858美高梅 17

    捌.三给输入/输出属性起小名

    把别称传进@Input/@Output装饰器,就可以为属性内定小名:

    @Output('myClick') clicks = new EventEmitter<string>();
    

    也得以在inputsoutputs数组中为属性钦点别称:

    @Directive({
        outputs: ['clicks: myClick']
    });
    
  9. 模板表明式操作符

    管道
    康宁导航操作符

    九.一 管道操作符(|)

    适用于小型调换。
    管道是二个简练的函数,它接受叁个输入值,并赶回调换结果。

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

    管道操作符能够串联:

    <div>
        Title through a pupe chain: {{ title | uppercase | lowercase }}
    </div>
    

    还足以接纳参数:

    <div>
        Birthday: {{ currentHero?.birthdate | date: 'longDate' }}
    </div>
    

    json管道用于调节和测试绑定:
    <div> {{ currentHero | json }} </div>

    运作结果如图 九-一 所示:

    4858美高梅 18

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

    ?.安然导航操作符用来保险出现在质量路线中的nullundefined,爱护视图渲染。

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

    如果currentHero不设有,那么地点的代码不加?.会爆发怎么着?
    草,整个视图都没有征兆就不见了了。
    用来代替*ngIf&&焚薮而田方案。

    <code>*ngIf 解决方案</code>
    <p><code>fuck.name: </code>{{ fuck.name }}</p>
    
    <code>&& 解决方案</code>
    <p><code>fuck.name: </code>{{ fuck && fuck.name }}</p>
    

    4858美高梅 19

    9.3 非空断言操作符(!)

    值得1提的是非空断言操作符不会制止出现null或undefined
    它只是告诉 TypeScript 的种类车检查查器对特定的性质表明式,不做
    “严俊空值检查”。

    假定大家张开了严厉空值检查,那将要用到这么些模板操作符,而任何意况下则是可选的。

    在 TypeScript 二.0
    中,大家得以选拔--strictNullChecks注解强制开启冷酷空值检查。TypeScript就能够保证不设有预期之外的null或undefined。
    在那种方式下,有品种的变量默许是不相同意null或undefined值的,假使有

    • 未赋值的变量,
    • 抑或总括把null或undefined赋值给不容许为空的变量,
    • 只要类型检查器在运维时期无法明确3个变量是null或undefined,
      项目检查器就能够抛出3个荒谬。

    在用*ngIf来检查过hero是已定义的事后,就能够断言hero属性一定是已定义的。

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

到这里模板语法的概述纵使是产生了。
以上贴图源码在GitHub。
上述最后更新:20一柒年八月10日1陆:4捌:2八


分外轻便

固然能够写出卓殊复杂的模版表明式,但不要那么去写。

正规是属性名或艺术调用。偶尔的逻辑取反 (!)
也还集合。其余情形下,应在组件中贯彻利用和专门的学问逻辑,使开垦和测试变得更易于。

表明式上下文 (Expression context)

独占鳌头的表明式上下文是组件实例。
The expression context is typically the component instance.

下例中 titleisUnchanged 均为 AppComponent 的属性。

{{title}}
changed

说明式的上下文能够包罗组件之外的目的。 比如模板输入变量 (let
hero)和模板引用变量(#heroInput)正是希图的上下文对象之1。

<div *ngFor="let hero of heroes">{{hero.name}}</div>
<input #heroInput> {{heroInput.value}}

用术语来讲,表明式上下文由模版变量,指令上下文对象(假使存在)和组件成员混合而成。假设所引述的称号在上述命名空间中有争辨,那么将会遵照模板变量,指令上下文和零部件成员的一一优先选项。

上例展现了三个命名争辨。组件有多个 hero 属性,*ngFor 定义了多少个
hero 模版变量。{{hero.name}} 中的 hero
指的是模板变量,而非组件属性。

模板表明式被局限于只可以访问来自表达式上下文中的成员。

幂等性

最佳使用幂等的表明式,因为它从不副成效,并且能晋升 Angular
改造检查实验的质量。

在 Angular
的术语中,幂等的表明式应该总是回到完全同样的事物,直到有个别注重值发生转移。

在独立的一遍事件循环中,被正视的值不应有退换。假若幂等的表明式重返一个字符串或数字,一而再调用它五次,也应当回到同样的字符串或数字。若是幂等的表明式重返1个对象(包罗一个List),一连调用它两遍,也理应回到同贰个对象的引用

<h三 id=”tmpsm”>模板语句</h3>

模板语句用来响应由绑定目的(如 HTML 成分、组件或指令)触发的事件。

模板语句就要事件绑定1节看到,它现身在=号左侧的引号中,就如那样:(event)="statement"

模板语句有副作用。那多亏用户输入更新应用状态的办法。不然,响应事件就不曾什么含义了。

1呼百应事件是 Angular
中“单向数据流”的另一面。在一回事件循环中,能够率性更换任哪儿方的其余东西。

和模板表明式同样,模板语句使用的语言也像
Dart。模板语句解析器和模板表明式解析器有所不相同,特别之处在于它帮忙中央赋值
(=) 和表达式链 (;)。

可是,有些 Dart 语法依然是不容许的:

  • newconst
  • 自增和自减运算符:++--
  • 操作并赋值,比方+=-=
  • 位操作符|&
  • 模板表明式运算符

表明式指南 (Expression guidelines)

模板表明式能产生或毁掉一个行使。应遵守原则:

壹. 从未可知的副成效

模板表明式除了目的属性的值以外,不应该更换使用的别的情形。那条规则是
Angular
“单向数据流”计谋的根底。在贰遍独自的渲染进程中,视图应该总是稳固的。

贰. 进行高效

Angular
试行模板表明式比大家想象的累累。当总计代价较高时,应该思念缓存那个从任何值总计得出的值。

TODO: 怎么样缓存?

3. 十分轻松

模板表明式应保持轻易,不要过度复杂。应在组件中得以落成接纳和事务逻辑,使支付和测试变得更便于。

4. 幂等性

采纳幂等的表达式未有副成效,并且能升高 Angular 更动检测的属性。
在 Angular
的术语中,幂等的表达式应该总是回到完全同样的东西,直到有个别重视值发生变动。

言语上下文

和表达式中千篇壹律,语句只好引用语句上下文中——平日是正值绑定事件的老大零件实例

模板语句不能够引用类的静态属性,也不能够引用一流变量或措施,举例从dart:html导入的window或者document。它们不能够一贯调用print或从dart:math导入的函数。

(click)="onSave()"中的 onSave 正是数量绑定组件实例中的方法。

说话上下文能够涵盖组件之外的靶子。模板引用变量纵然盘算上下文对象之一。在事变绑定语句中,平时会看到被保留的$event标志,它意味着触发事件的“音讯”或“有效载荷”。

模板语句 (Template statements)

模板语句用来响应由绑定目标(如 HTML 元素、组件或指令)触发的轩然大波。
A template statement responds to an event raised by a binding target
such as an element, component, or directive.

语法:(event)=”statement”

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

模板语句有副功效。那是事件的关键所在,能够依据用户的位移更新应用状态。
A template statement has a side effect. That’s the whole point of an
event. It’s how you update application state from user action.

模板语句解析器 (template statement parser) 和模板表明式解析器 (template
expression parser) 有所分裂,特别之处在于它帮助大旨赋值 (=) 和表明式链
( ;, )。

一点 JavaScript 语法仍旧是不相同意的:

  • new 运算符
  • 自增和自减运算符:++--
  • 操作并赋值,比如 +=-=
  • 位操作符 |&
  • 模板表明式运算符
言辞指南

和表明式同样,制止写复杂的沙盘语句。常规是函数调用大概性质赋值。

今昔,对模板表明式和语句有了几许以为到了吗。除插值表明式外,还有多姿多彩的数据绑定语法,是读书它们的时候了。

<h叁 id=”bind”>绑定语法:大概浏览</h三>

多少绑定是一种体制,用来和睦用户所见和采取数据。即便我们能往 HTML
推送值也许从 HTML
拉取值,但借使把这么些小节交给数据绑定框架管理,应用会更易于编写、阅读和护卫。
只要简单地在绑定源和目的 HTML 成分之间注解绑定,框架就能达成那项职业。

Angular 提供了多姿多彩的多少绑定,本章将种种探讨。首先,从高层视角来探视
Angular 数据绑定和它的语法。

依附数据流的方向,能够把富有绑定归为3类。 每壹类都有它特殊的语法:

数据方向 语法 绑定类型
单向-从数据源流向视图目标 {{expression}}
[target] = "expression"
bind-target = "expression"
插值表达式Property Attribute类样式
单向-从视图目标到数据源 (target) = "statement"
on-target = "statement"
事件
双向 [(target)] = "expression"
bindon-target = "expression"
双向

除外插值表达式之外的绑定类型,在等号左侧是目标名,无论是包在括号中([]())依然用前缀形式(bind-on-bindon-) 。

何以是“目的”?在回答那么些难点以前,我们不能不先挑衅下小编,尝试用另1种格局来审视模板中的
HTML。

言辞上下文 (Statement context)

和表明式中同样,语句只好引用语句上下文中——常常是正在绑定事件的尤其组件实例。

话语上下文能够引用模板本人上下文中的品质。下例把模版的 $event
对象、模板输入变量(let
hero)和模板引用变量(#heroForm)传给了组件中的三个轩然大波管理器方法。

<button (click)="onSave($event)">Save</button>
<button *ngFor="let hero of heroes" (click)="deleteHero(hero)">{{hero.name}}</button>
<form #heroForm (ngSubmit)="onSubmit(heroForm)"> ... </form>

模板语句无法引用全局命名空间的其它事物。比方不可能引用 window
document,也不可能调用 console.logMath.max

新的沉思模型

数码绑定的威力和允许用自定义标志扩张 HTML 词汇的力量,轻巧误导我们把模版
HTML 当成 HTML+

也对,它是 HTML+。但它也跟我们熟悉的 HTML
有着显著的不如。我们须求1种新的构思模型。

在健康的 HTML 开拓进度中,大家使用 HTML
成分制造视觉结构,通过把字符串常量设置到成分的attribute来修改那么些元素。

<div class="special">Mental Model</div>
[站外图片上传中……(3)]
<button disabled>Save</button>

在 Angular 模板中,我们仍使用一样的艺术来创建布局和初叶化attribute值。

下一场,用包装了 HTML 的机件创制新因素,并把它们作为原生 HTML
成分在模板中应用。

<!-- Normal HTML -->
<div class="special">Mental Model</div>
<!-- Wow! A new element! -->
<hero-detail></hero-detail>

这就是HTML+。

当今启幕学习数据绑定。大家相遇的首先种多少绑定看起来是如此的:

<!-- Bind button disabled state to `isUnchanged` property -->
<button [disabled]="isUnchanged">Save</button>

过会儿再认知那些神奇的方括号记法。直觉告诉大家,我们正在绑定按键的disabled
attribute。并把它设置为组件的isUnchanged个性的近来值。

但我们的直觉是错的!平日的 HTML
思维情势在误导大家。实际上,1旦起先数据绑定,就不再跟 HTML attribute
打交道了。这里不是设置 attribute,而是设置 DOM 成分、组件和下令的
property。

HTML attribute 与 DOM property 的对比

要想明白 Angular 绑定怎么样专门的学问,珍视是搞清 HTML attribute 和 DOM
property 之间的分别。

attribute 是由 HTML 定义的。property 是由 DOM (Document Object
Model) 定义的

  • 一点点 HTML attribute 和 property 之间全体 一:壹 的照耀,如id
  • 稍微 HTML attribute 没有相应的 property,如colspan
  • 稍稍 DOM property 未有对号入座的 attribute,如textContent
  • 汪洋 HTML attribute看起来映射到了property…… 但却不像大家想的那样!

末尾1类尤其令人猜忌…… 除非我们能精通这么些广阔原则:

attribute 开端化 DOM property,然后它们的天职就变成了。property
的值能够转移;attribute 的值无法改动

譬如说,当浏览器渲染<input type="text" value="Bob">时,它将创立相应
DOM 节点,其value property 被早先化为 “Bob”。

当用户在输入框中输入 “萨莉” 时,DOM 成分的value property 产生了
“Sally”。 可是那几个 HTML value attribute 保持不改变。倘若我们读取 input
成分的
attribute,就能发觉真正没变:input.getAttribute('value') // 返回 "Bob"

HTML attribute value钦赐了起先值;DOM value property 是现阶段值。

disabled attribute 是另三个奇特的例子。开关的disabled property
false,因为私下认可景况下开关是可用的。当我们抬高disabled attribute
时,只要它出现了,按键的disabled property
就初步化为true,于是按钮就被剥夺了。

加上或删除disabled attribute会禁止使用或启用那么些按键。但 attribute
的值非亲非故主要,那就是我们为啥无法通过
<button disabled="false">仍被禁用</button>那种写法来启用按键。

安装开关的disabled property(如,通过 Angular
绑定)能够禁止使用或启用这几个按钮。那便是 property 的价值。

不怕名字如出一辙,HTML attribute 和 DOM property 也不是一样的东西

那句话很首要,我们再重申一次:

模板绑定是经过 property 和事件来行事的,而不是 attribute

在 Angular 的社会风气中,attribute
唯1的功能是用来伊始化成分和下令的动静。当进行数量绑定期,只是在与成分和下令的
property 和事件打交道,而 attribute 就完全靠边站了。

把这么些理念模型紧紧的印在脑子里,接下去,学习怎么是绑定目的。

说话指南 (Expression guidelines)

和表达式一样,防止写复杂的模版语句。常规是函数调用大概性质赋值。

绑定目的

多少绑定的对象是 DOM
中的有个别事物。依据绑定类型,这些目标只怕是(成分 | 组件 |
指令的)property、(成分 | 组件 | 指令的)事件,或(极个别情状下)
attribute 名。下边是的汇总表:

绑定类型 目标 示例
property 元素属性
组件属性
指令属性
<img [src] = "heroImageUrl">
<hero-detail [hero]="currentHero"></hero-detail>
<div [ngClass] = "{selected: isSelected}"></div>
事件 元素事件
组件事件
指令事件
<img [src] = "heroImageUrl">
<hero-detail [hero]="currentHero"></hero-detail>
<div [ngClass] = "{selected: isSelected}"></div>
双向 事件和property <input [(ngModel)]="heroName">
Attribute attribute(例外情况) <button [attr.aria-label]="help">help</button>
CSS 类 class属性 <div [class.special]="isSpecial">Special</div>
样式 style属性 <button [style.color] = "isSpecial ? 'red' : 'green'">

让我们从结构性云层中走出去,看看各样绑定类型的具体景况。

<h叁 id=”prop”>属性绑定</h3>

当要把视图成分的属性 (property) 设置为模板表明式时,就要写模板的属性
(property) 绑定

最常用的性质绑定是把成分属性设置为组件属性的值。上面这些事例中,image
成分的src属性会被绑定到零部件的heroImageUrl属性上:

<img [src]="heroImageUrl">

另一个事例是当组件说它isUnchanged(未变动)时禁止使用开关:

<button [disabled]="isUnchanged">Cancel is disabled</button>

另3个例子是安装指令的习性:

<div [ngClass]="classes">[ngClass] binding to the classes property</div>

还有另四个例证是设置自定义组件的模子属性(那是父亲和儿子组件之间通信的主要渠道):

<hero-detail [hero]="currentHero"></hero-detail>

绑定语法:概览

绑定的花色能够依赖数据流的势头分成3类:

  • 从数额源到视图(source-to-view)
  • 从视图到数据源(view-to-source)
  • 双向的从视图到数据源再到视图(view-to-source-to-view)。

单向 source-to-view

语法 绑定类型
{{expression}} 插值表达式
[target]="expression" / bind-target="expression" Property, Attribute 类样式

单向 view-to-source

语法 绑定类型
(target)="statement" / on-target="statement" 事件

双向

语法 绑定类型
[(target)]="expression" / bindon-target="expression" 双向

绑定类型(插值表明式除了那么些之外)有一个目的名,它座落等号右侧,它是
Property 的名字(注意它不是 Attribute 的名字)。

单向输入

人人平时把质量绑定描述成单向数据绑定,因为值的流淌是单向的,从组件的多寡属性流向目的成分的属性。

大家无法利用品质绑定从目的成分拉取值,也不能够绑定到对象成分的属性来读取它。只好设置它。

也无法使用性质绑定来调用目标成分上的不2秘籍。

一经这几个成分触发了风浪,大家可以透过事件绑定来监听它们。

假使必须读取目的成分上的习性或调用它的某部方法,得用另壹种本领。参见
API 参考手册中的 ViewChildContentChild

新的沉思模型

绑定目的

卷入在方括号中的成分属性名标志着对象属性。下列代码中的目的属性是 image
元素的src属性。

<img [src]="heroImageUrl">

稍加人欢娱用bind-前缀的可选格局,并号称正式情势

[站外图片上传中……(4)]

目标的名字总是 property
的名字。就算它看起来和别的名字同样。看到src时,恐怕会把它当作
attribute。不!它不是!它是 image 元素的 property 名。

要素属性大概是最广泛的绑定目标,但 Angular
会先去看这些名字是不是是有个别已知指令的属性名,就好像上面包车型客车例证中壹律:

<div [ngClass]="classes">[ngClass] binding to the classes property</div>

严酷来说,Angular
正在同盟指令的输入属性的名字。那些名字是命令的inputs列表中所列的名字,只怕是富含@Input()注脚的属性。那么些输入属性被映射为命令自个儿的品质。

比如名字未有相称寒食知指令或因素的属性,Angular
就能够告知“未知指令”的谬误。

HTML attribute 与 DOM property 的对比

attribute 是由 HTML 定义的。property 是由 DOM (Document Object Model)
定义的。

  • 一点点 HTML attribute 和 property 之间有着 一:一 的映射,如 id。
  • 有点 HTML attribute 未有对号入座的 property,如 colspan。
  • 稍加 DOM property 未有对应的 attribute,如 textContent。

<!-- Bind button disabled state to `isUnchanged` property -->
<button [disabled]="isUnchanged">Save</button>

假定开始数据绑定,就不再跟 HTML attribute 打交道了。这里不是安装
attribute,而是设置 DOM 成分、组件和指令的 property。

attribute 最先化 DOM property,然后它们的职分就完了了。property
的值能够变动,是当前值;attribute 的值不能更改,是开首值。

就算名字同样,HTML attribute 和 DOM property 也不是同同样东西。

模板绑定是透过 property 和事件来干活的,而不是 attribute。在 Angular
的世界中,attribute 唯壹的职能是用来开首化成分和指令的图景。
当举行数据绑按时,只是在与成分和下令的 property 和事件打交道。

扫除副功用

正如曾探究过的,模板表明式的总结不可能有可知的副功能。表明式语言本身能够提供一些康宁保险。不能在质量绑定表明式中对其余事物赋值,也不能够选取自增、自减运算符。

当然,表达式恐怕会调用具有副作用的性质或措施。但 Angular
无法知道那点,也没办法阻止大家。

表达式中得以调用像getFoo()如此的点子。唯有大家了解getFoo()干了何等。
假若getFoo()变动了有些东西,恰好又绑定到个这几个事物,我们就恐怕把温馨坑了。Angular
可能来得也也许不展现变化后的值。Angular
还或者检测到变化,并抛出警告型错误。一般提出是,只绑定数据属性和那么些只重临值而不做其余职业的主意。

绑定目的 (Binding targets)

数量绑定的靶子是 DOM 中的有个别事物。

Property 绑定类型

目标 范例
Element property <img [src]="heroImageUrl">
Component property <hero-detail [hero]="currentHero"></hero-detail>
Directive property <div [ngClass]="{special: isSpecial}"></div>

事件绑定类型

目标 范例
Element event <button (click)="onSave()">Save</button>
Component event <hero-detail (deleteRequest)="deleteHero()"></hero-detail>
Directive event <div (myClick)="clicked=$event" clickable>click me</div>

双向绑定类型

目标 范例
Event and property <input [(ngModel)]="name">

Attribute 绑定类型

目标 范例
Attribute(例外情况) <button [attr.aria-label]="help">help</button>

CSS 类绑定类型

目标 范例
class property <div [class.special]="isSpecial">Special</div>

体制绑定类型

目标 范例
style property <button [style.color]="isSpecial ? 'red' : 'green'">

回到妥善的类别

模板表明式应该回到目的属性所需项目标值。假设目的属性想要个字符串,就再次来到字符串。要是目的属性想要个数字,就回来数字。假若目的属性想要个目的,就回去对象。

HeroDetail组件的hero质量想要四个Hero目的,那就在性能绑定中标准地给它3个Hero对象:

<hero-detail [hero]="currentHero"></hero-detail>

在自己争论模式,假诺模板表明式结果类型和对象属性类型不匹配,会抛出一个连串卓殊错误。

本性绑定 (Property binding) [property]

当要把视图成分的属性 (property) 设置为模板表明式时,将在写模板的属性
(property) 绑定。

最常用的天性绑定是把成分属性设置为组件属性的值。

<img [src]="heroImageUrl">

上例表达:image 元素的 src 属性会被绑定到零部件的 heroImageUrl
属性上。

其它示例:

<button [disabled]="isUnchanged">Cancel is disabled</button>

<div [ngClass]="classes">[ngClass] binding to the classes property</div>

<hero-detail [hero]="currentHero"></hero-detail>

别忘了方括号

方括号报告 Angular 要计算模板表明式。即便忘了加方括号,Angular
会把这几个表达式当做字符串常量对待,并用该字符串来初步化目的属性。它不会一个钱打二十五个结这些字符串。

并非出现如此的失误:

<!-- ERROR: HeroDetailComponent.hero expects a
     Hero object, not the string "currentHero" -->
  <hero-detail hero="currentHero"></hero-detail>

在检查方式,下面的代码再次来到3个种类卓殊:String isn't a subtype of Hero.

单向输入 (One-way in)

人人日常把品质绑定描述成单向数据绑定,因为值的流动是单向的,从组件的数量属性流动到目的成分的习性。

注意:

  • 不能选取性质绑定来从目标成分拉取值
  • 无法绑定到目的元素的习性来读取它。只好设置它。
  • 也不可能利用属性 绑定 来调用目标元素上的不二等秘书技。

假设非得读取目的成分上的属性或调用它的某个方法, 参见 API 参考手册中的
ViewChild

ContentChild。

一次性字符串开端化

当下列标准满足时,应该省略括号:

  • 目的属性接受字符串值。
  • 字符串是个固定值,能够间接统1到模块中。
  • 那些初始值永不退换。

咱俩平日这么在正规 HTML 中用那种格局起首化
attribute,那种格局也能够用在初步化指令和零部件的性质。上面那么些事例把HeroDetailComponentprefix属性起先化为定位的字符串,而不是模板表明式。Angular
设置它,然后忘记它。

<hero-detail prefix="You are my" [hero]="currentHero"></hero-detail>

作为相比较,[hero]绑定是组件的currentHero质量的活绑定,它会直接随着更新。

绑定目的

三种写法:

<img [src]="heroImageUrl">

![](heroImageUrl)

bind- 前缀的写法被号称标准方式 (佳能ical form)。

要素属性或者是最广大的绑定目标,但 Angular
会先去看那几个名字是不是是有个别已知指令的属性名。

<div [ngClass]="classes">[ngClass] binding to the classes property</div>

严俊来讲,Angular 正在合作指令的输入属性的名字。 那些名字是命令的
inputs 数组中所列的名字,或然是带有 @Input() 装饰器的性质。
那个输入属性被映射为命令自身的习性。
Technically, Angular is matching the name to a directive input, one
of the property names listed in the directive’s inputs array or a
property decorated with @Input(). Such inputs map to the directive’s
own properties.

要是名字未有相称桃月知指令或因素的性质,Angular
就能报告“未知指令”的荒唐。

质量绑定还是插值表达式?

小编们一般得在插值表达式和本性绑定之间做出采纳。下列这几对绑定做的事务一模一样:

<p>[站外图片上传中……(5)] is the <i>interpolated</i> image.</p>
<p><img [src]="heroImageUrl"> is the <i>property bound</i> image.</p>

<p>"{{title}}" is the <i>interpolated</i> title.</p>
<p>"" is the <i>property bound</i> title.</p>

在大部气象下,插值表明式是更有益的备选项。实际上,在渲染视图在此之前,Angular
把那些插值表明式翻译成相应的属性绑定。

从未有过本事上的理由能操纵哪一种方式更加好。我们协理于可读性,所以倾向于插值表明式。建议创建代码风格规则,选用1种方式,那样,既服从了平整,又能让手下的职务做起来更自然。

铲除副效率

诚如建议是,只绑定数据属性和那个只再次来到值而不做其余业务的秘诀。

剧情安全

假如上边包车型客车恶心内容.

String evilTitle = 'Template <script>alert("evil never sleeps")</script>Syntax';

幸运的是,Angular 数据绑定对惊恐 HTML
有幸免。在展现它们以前,它对剧情先进行消毒。不管是插值表明式依旧性质绑定,都不会允许带有
script 标签的 HTML 泄漏到浏览器中。

<p>"{{evilTitle}}" is the <i>interpolated</i> evil title.</p>
<p>"" is the <i>property bound</i> evil title.</p>

插值表达式管理 script
标签与品质绑定有所区别,可是两者都只渲染未有加害的从头到尾的经过。

<h3 id=”attr”>attribute、class 和 style 绑定</h3>

模板语法为那三个不太相符采纳品质绑定的情形提供了尤其的单向数据绑定情势。

回到稳妥的品种

模板表明式应该回到目的属性所需项目的值。

attribute 绑定

能够因此 attribute 绑定来平素设置 attribute 的值。

那是“绑定到对象属性
(property)”那条规则中有一无二的区别。这是唯一的能创建和设置 attribute
的绑定方式。

本章中,通篇都在说通过品质绑定来设置成分的习性总是好于用字符串设置
attribute。为啥 Angular 还提供了 attribute 绑定呢?

因为当成分未有质量可绑的时候,就必须利用 attribute 绑定

考虑 ARIASVGtable 中的 colspan/rowspan
attribute。它们是原原本本的 attribute,未有相应的品质可供绑定。

假定想写出类似上边那样的东西,现状会令我们悲哀:

<tr><td colspan="{{1 + 1}}">Three-Four</td></tr>

会获取那么些荒唐:

// 模板解析错误:不能绑定到 'colspan',因为它不是已知的原生属性
Template parse errors:
Can't bind to 'colspan' since it isn't a known native property

正如提示中所说,<td>要素未有colspan性子。不过插值表达式和天性绑定只可以设置属性,不可能安装
attribute

小编们需求 attribute 绑定来创设和绑定到那般的 attribute。

attribute
绑定的语法与本性绑定类似。但方括号中的部分不是因素的属性名,而是由attr前缀,一个点
(.) 和 attribute 的名字组成。能够由此值为字符串的表明式来设置
attribute 的值。

这里把[attr.colspan]绑定到三个总计值:

<table border=1>
  <!--  expression calculates colspan=2 -->
  <tr><td [attr.colspan]="1 + 1">One-Two</td></tr>

  <!-- ERROR: There is no `colspan` property to set!
    <tr><td colspan="{{1 + 1}}">Three-Four</td></tr>
  -->

  <tr><td>Five</td><td>Six</td></tr>
</table>

attribute 绑定的基本点用例之一是设置 A普拉多IA
attribute(译注:A凯雷德IA指可访问性,用于给残障职员访问网络提供便宜),就如这几个例子中同样:

<!-- create and set an aria attribute for assistive technology -->
<button [attr.aria-label]="actionName">{{actionName}} with Aria</button>

别忘了方括号

CSS 类绑定

借助 CSS 类绑定,可以从要素的class attribute 上助长和移除 CSS
类名。

CSS
类绑定绑定的语法与本性绑定类似。但方括号中的部分不是因素的属性名,而是由class前缀,一个点
(.)和 CSS
类的名字组成,其中后两片段是可选的。形如:[class.class-name]

下列例子示范了怎样通过 CSS 类绑定来丰盛和移除应用的 “special”
类。不用绑定直接设置 attribute 时是如此的:

<!-- standard class attribute setting  -->
<div class="bad curly special">Bad curly special</div>

能够把它改写为绑定到所需 CSS
类名的绑定;那是三个照旧全有大概全无的替换型绑定。 (译注:即当 badCurly
有值时 class 这几个 attribute 设置的内容会被完全覆盖)

<!-- reset/override all class names with a binding  -->
<div class="bad curly special"
     [class]="badCurly">Bad curly</div>

最终,能够绑定到特定的类名。当模板表达式的求值结果是真值时,Angular
会增多这些类,反之则移除它。

<!-- toggle the "special" class on/off with a property -->
<div [class.special]="isSpecial">The class binding is special</div>

<!-- binding to `class.special` trumps the class attribute -->
<div class="special"
     [class.special]="!isSpecial">This one is not so special</div>

虽说那是切换单一类名的好点子,但大家一般更爱好使用 NgClass命令
来同时管理七个类名。

一回性字符串初阶化

当满意下列原则时,应该省略括号:

  • 对象属性接受字符串值。
  • 字符串是个固定值,能够一直统1到模块中。
  • 本条开始值永不改造。

<hero-detail prefix="You are my" [hero]="currentHero"></hero-detail>

体制绑定

因此体制绑定,能够设置内联样式。

体制绑定的语法与脾气绑定类似。但方括号中的部分不是因素的属性名,而由style前缀,一个点
(.)和 CSS 样式的性质名组成。形如:[style.style-property]

<button [style.color] = "isSpecial ? 'red': 'green'">Red</button>
<button [style.background-color]="canSave ? 'cyan': 'grey'" >Save</button>

有个别样式绑定中的样式带有单位。在此处,我们依据条件用 “em” 和 “%”
来设置字体大小的单位。

<button [style.font-size.em]="isSpecial ? 3 : 1" >Big</button>
<button [style.font-size.%]="!isSpecial ? 150 : 50" >Small</button>

尽管那是安装单同样式的好法子,但我们常见更欣赏使用NgStyle 指令
来同时安装五个内联样式。

注意,样式属性命名方式可以用中划线命名法,像上面的一律,也足以用驼峰式命名法,如fontSize

在Angular Ddart
中,命名样式属性名使用驼峰和中划线风格是1二分的,唯有中划线命名是被dart:html的CssStyleDeclaration方法getPropertyValue()setProperty()公认的。由此,大家引入仅使用中划线办法为样式属性命名。

<h叁 id=”event”>事件绑定</h叁>

到最近截止我们境遇的绑定的数据流都以单向的:从组件到成分

用户不会只望着显示屏看。他们会在输入框中输入文本。他们会从列表中挑选条款。他们会点击开关。这类用户动作恐怕引致反向的数据流:从要素到零部件

精晓用户动作的独一无二方法是监听某个事件,如开关、鼠标移动、点击和触摸显示屏。能够由此Angular 事件绑定来声称对怎么样用户动作感兴趣。

事件绑定语法由等号右侧带圆括号的目标事件和右边手引号中的模板语句组成。下边事件绑定监听开关的点击事件。每当点击产生时,都会调用组件的onSave()方法。

<button (click)="onSave()">Save</button>

质量绑定仍旧插值表达式?

在大诸多动静下,插值表明式是更便宜的希图项。实际上,在渲染视图在此以前,Angular
把这个插值表明式翻译成相应的本性绑定。

<p>![]({{heroImageUrl}}) is the <i>interpolated</i> image.</p>
会被自动翻译成
<p><img [src]="heroImageUrl"> is the <i>property bound</i> image.</p>

<p>"{{title}}" is the <i>interpolated</i> title.</p>
会被自动翻译成
<p>"" is the <i>property bound</i> title.</p>

当要渲染的数据类型是字符串时,基于可读性思索,提议利用插值表明式。其余情状则必须选取性质绑定。

对象事件

圆括号中的名称——比如(click)——标识出目标事件。在上边例子中,目的是按键的
click 事件。

<button (click)="onSave()">Save</button>

些微人更欣赏带on-前缀的希图格局,称之为专门的职业格局

<button on-click="onSave()">On Save</button>

要素事件恐怕是更广阔的靶子,但 Angular
会先看这些名字是不是能相配桃月知指令的事件性质,就如上边那些事例:

<!-- `myClick` is an event on the custom `MyClickDirective` -->
<div (myClick)="clickMessage=$event">click with myClick</div>

假设那些名字没能相称到成分事件或已知指令的输出属性,Angular
就能够报“未知指令”错误。

剧情安全

随意是插值表明式依然性质绑定,都不会同意带有 script 标签的 HTML
泄漏到浏览器中。
插值表明式管理 script
标签与质量绑定有所区别,可是互相都只渲染未有危机的剧情。

evilTitle = 'Template <script>alert("evil never sleeps")</script>Syntax';

<!--Angular generates warnings for these two lines as it sanitizes them 
WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).-->
<p>"{{evilTitle}}" is the <i>interpolated</i> evil title.</p>
<p>"" is the <i>property bound</i> evil title.</p>

$event 和事件管理语句

在事变绑定中,Angular 会为对象事件设置事件管理器。

当事件发生时,那么些管理器会实行模板语句。规范的沙盘语句平常涉及到响应事件实践动作的接收器,举个例子从
HTML 控件中获取值,并存入模型。

绑定会由此名为$event的风云目的传送关于此事件的音讯(包罗数据值)。

事件目的的模样取决于目的事件。假如目标事件是原生 DOM
成分事件,$event就是
DOM事件目标,它有像targettarget.value这般的属性。

牵记这几个范例:

<input [value]="currentHero.firstName"
       (input)="currentHero.firstName=$event.target.value" >

地点的代码通过绑定到firstName质量来设置输入框的value属性。要监听对值的改动,代码绑定到输入框的input事件。当用户变成更换时,input事件被触发,并在含有了
DOM 事件对象 ($event) 的前后文中绑定实践那条语句。

要更新firstName品质,将在通过路线$event.target.value来赢得改动后的值。

1旦事件属于指令(回看一下,组件是命令的壹种),那么$event切切实实是怎么由指令决定。

attribute、class 和 style 绑定

接纳 伊芙ntEmitter 完成自定义事件

司空眼惯,指令使用 Angular EventEmitter
来触发自定义事件。指令成立三个EventEmitter实例,并且把它看作性能暴表露来。指令调用EventEmitter.emit(payload)来触发事件,可以流传任何事物作为音信载荷。
父指令通过绑定到那几个个性来监听事件,并通过$event对象来拜访载荷。

考虑HeroDetailComponent用以体现英豪的信息,并响应用户的动作。纵然HeroDetailComponent包括删除按键,但它本人并不知道该怎么着删除那么些大胆。
最佳的做法是接触事件来告诉“删除用户”的请求。

下边包车型地铁代码节选自HeroDetailComponent

template: '''
  <div>
    [站外图片上传中……(6)]

      {{prefix}} {{hero?.fullName}}

    <button (click)="delete()">Delete</button>
  </div>'''

  // This component make a request but it can't actually delete a hero.
final deleteRequest = new EventEmitter<Hero>();

void delete() {
  deleteRequest.emit(hero);
}

组件定义了deleteRequest属性,它是EventEmitter实例。当用户点击删除时,组件会调用delete()方法,让EventEmitter发出二个Hero对象。

目前,假如有个宿主的父组件,它绑定了HeroDetailComponentdeleteRequest事件。

<hero-detail (deleteRequest)="deleteHero($event)" [hero]="currentHero"></hero-detail>

deleteRequest事件触发时,Angular 调用父组件的deleteHero方法,
$event变量中传播要去除的英勇(来自HeroDetail)。

attribute 绑定

语法:[attr.attribute-name]

能够经过 attribute 绑定来一贯设置 attribute
的值,因为当元素未有质量可绑的时候,就亟须使用 attribute 绑定。

<tr><td colspan="{{1 + 1}}">Three-Four</td></tr>

该语句会报错如下:

Template parse errors:
Can't bind to 'colspan' since it isn't a known native property
(模板解析错误:不能绑定到 'colspan',因为它不是已知的原生属性)

科学的写法:

<table border=1>
  <!--  expression calculates colspan=2 -->
  <tr><td [attr.colspan]="1 + 1">One-Two</td></tr>

  <!-- ERROR: There is no `colspan` property to set!
    <tr><td colspan="{{1 + 1}}">Three-Four</td></tr>
  -->

  <tr><td>Five</td><td>Six</td></tr>
</table>

attribute 绑定的基本点用例之一是设置 ARIA
attribute

A汉兰达IA 指可访问性,用于给生理残疾行动障碍者人员访问网络提供便利。

<!-- create and set an aria attribute for assistive technology -->
<button [attr.aria-label]="actionName">{{actionName}} with Aria</button>

模板语句有副作用

deleteHero办法有副成效:它删除了3个神勇。模板语句的副功能不止没难题,反而就是所企望的。

删去那一个大胆会更新模型,还大概接触别的修改,包蕴向远端服务器的查询和保留。
那个改造通过系统开始展览扩散,并最后展现到当前以及其余视图中。

<h三 id=”two”>双向数据绑定</h三>

大家常常索要出示数据属性,并在用户作出退换时更新该属性。

在要素层面上,既要设置成分属性,又要监听成分事件变化。

Angular
为此提供壹种特殊的双向数据绑定语法:[(x)]。[(x)]语法结合了品质绑定的方括号[x]和事件绑定的圆括号(x)

当一个要素具有足以设置的品质x和呼应的事件xChange时,解释[(x)]语法就便于多了。上边包车型客车SizerComponent适合这几个情势。它有size天性和陪伴的sizeChange事件:

import 'dart:math';
import 'package:angular2/core.dart';

@Component(
    selector: 'my-sizer',
    template: '''
      <div>
        <button (click)="dec()" title="smaller">-</button>
        <button (click)="inc()" title="bigger">+</button>
        <label [style.font-size.px]="size">FontSize: {{size}}px</label>
      </div>''')
class MySizerComponent {
  static final defaultPxSize = 14;

  @Input()
  String size;

  @Output()
  var sizeChange = new EventEmitter<String>();

  void dec() => resize(-1);
  void inc() => resize(1);

  void resize(num delta) {
    final numSize = num.parse(size, (_) => defaultPxSize);
    size = min(40, max(8, numSize + delta)).toString();
    sizeChange.emit(size);
  }
}

size的开端值是一个输入值,来自属性绑定。(译注:注意size前面包车型地铁@Input)点击开关,在小小/最大值范围限定内扩展可能缩减size。然后用调治后的size触发sizeChange事件。

下面包车型地铁例子中,AppComponent.fontSize被双向绑定到SizerComponent

<my-sizer [(size)]="fontSizePx"></my-sizer>
<div [style.font-size.px]="fontSizePx">Resizable Text</div>

SizerComponent.size伊始值是AppComponent.fontSizePx。点击按钮时,通过双向绑定更新AppComponent.fontSizePx。被涂改的AppComponent.fontSizePx透过体制绑定,更改文本的体现大小。试一下在线例子。

双向绑定语法实际上是性质绑定和事件绑定的语法糖。Angular将SizerComponent的绑定分解成那样:

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

$event变量包罗了SizerComponent.sizeChange事件的荷载。当用户点击开关时,Angular
$event赋值给AppComponent.fontSizePx

分明,比起独立绑定属性和事件,双向数据绑定语法显得至极有益。

咱俩期待能在像<input><select>那般的 HTML 成分上选取双向数据绑定。
可惜,原生 HTML 元素不依据x值和xChange事件的形式。

幸运的是,Angular 以 NgModel
指令为大桥,允许在表单成分上使用双向数据绑定。

<h三 id=”ngmodel”>使用 NgModel 进行双向数据绑定</h三>

当开拓数据输入表单时,咱们平时希望能显得数据属性,并在用户做出退换时更新该属性。

使用NgModel指令展开双向数据绑定让它变得更为轻松。请看下例:

<input [(ngModel)]="currentHero.firstName">

CSS 类绑定

语法:[class.class-name]

<!-- standard class attribute setting  -->
<div class="bad curly special">Bad curly special</div>

<!-- reset/override all class names with a binding  -->
<div class="bad curly special" [class]="badCurly">Bad curly</div>

<!-- toggle the "special" class on/off with a property -->
<div [class.special]="isSpecial">The class binding is special</div>

<!-- binding to `class.special` trumps the class attribute -->
<div class="special" [class.special]="!isSpecial">This one is not so special</div>

一般说来更爱好使用 ngClass 指令来还要管理多少个类名。

[(ngModel)]内幕

想起一下firstName的绑定,值得注意的是,可以透过独家绑定<input>元素的value属性和input事件来贯彻均等的功能。

<input [value]="currentHero.firstName"
       (input)="currentHero.firstName=$event.target.value" >

诸如此类很鸠拙。什么人能记住哪个成分属性用于安装,哪个用于产生用户改变?怎么样从输入框中提抽取当下来得的公文,以便更新数据属性?哪个人想每便都去查一回?

ngModel一声令下通过它自身的ngModel输入属性和ngModelChange出口属性隐藏了那些繁琐的底细。

<input
  [ngModel]="currentHero.firstName"
  (ngModelChange)="currentHero.firstName=$event">

ngModel数码属性设置成分的 value
属性,ngModelChange事件性质量监督听成分 value 的成形。

每一种成分的性子各不相同样,所以NgModel命令只幸而有个别一定表单成分上行使,举例输入文本框,因为它们扶助
ControlValueAccessor。

唯有写2个正好的值访问器,不然不可能把[(ngModel)]用在自定义组件上。但值访问器本事超过了本章的界定。对于不能够垄断其
API 的 Angular 组件或许 Web 组件,或许供给为其增添 value accessor

然则对于我们能说了算的 Angular
组件来讲,这么做就没有供给了。因为能够钦赐值和事件性质名字来开始展览着力的
Angular 双向绑定语法,完全不用NgModel。

独立的ngModel绑定相比较直接绑定成分的原生属性是个立异,但仍可以够做得更加好。

我们不应有聊起数据属性三回。Angular
应该能捕捉组件的数额属性,并用一条评释来设置它——依据[(ngModel)]语法:

<input [(ngModel)]="currentHero.firstName">

[(ngModel)]正是我们所需的总体呢?有未有如何理由要求回退到它的开始展览格局?

[(ngModel)]语法只好安装二个数量绑定属性。如若要求做更加多或不一致的思想政治工作,就得要好用它的展开方式。

来做点顽皮的事呢,比方强制让输入值形成大写方式:

<input
  [ngModel]="currentHero.firstName"
  (ngModelChange)="setUpperCaseFirstName($event)">

<h三 id=”direct”>内置指令</h三>

上壹版本的 Angular 中带有了高出 柒拾多少个放置指令。社区进献了越多,那还没算为其中采纳而创制的大队人马私有指令。

在新版的 Angular 中无需那么多指令。使用越来越强劲、更有着表现力的 Angular
绑定系统,其实可以高达同等的作用。假诺能用轻巧的绑定到达目标,为何还要创造指令来拍卖点击事件呢?

<button (click)="onSave()">Save</button>

大家照样能够从简化复杂任务的下令中受益。Angular
发表时仍旧蕴藏内置指令,只是没那么多了。我们仍会写自个儿的指令,只是没那么多了。

上面来看一下那么些最常用的嵌入指令。

<h4 id=”class”>NgClass</h4>

我们平时用动态增进或删除 CSS
类的格局来决定成分如何显示。通过绑定到NgClass,能够同时加上或移除多少个类。

CSS 类绑定是丰硕或删除单个类的最棒路线。

<!-- toggle the "special" class on/off with a property -->
<div [class.special]="isSpecial">The class binding is special</div>

当想要同时丰裕或移除多少个 CSS 类时,NgClass一声令下大概是更加好的挑选。

绑定到二个 key:value
方式的支配Map,是运用NgClass的好点子。这一个目的中的各个 key 都是二个CSS 类名,假若它的 value 是true,那些类就能够被抬高,不然就能够被移除。

下边包车型大巴机件方法setClasses管住了三个 CSS 类的场合:

  Map<String, bool> setClasses() {
    final classes = {
      'saveable': canSave, // true
      'modified': !isUnchanged, // false
      'special': isSpecial // true
    };
    // compensate for DevMode (sigh)
    if (JSON.encode(_previousClasses) == JSON.encode(classes))
      return _previousClasses;
    _previousClasses = classes;
    return classes;
  }

今昔,可以增进NgClass属性绑定,它会调用setClasses,并相应地安装成分的类:

<div [ngClass]="setClasses()">This div is saveable and special</div>

<h4 id=”style”>NgStyle</h4>

咱俩得以依据组件的情事动态设置内联样式。NgStyle绑定能够而且安装多少个内联样式。

体制绑定是安装单同样式值的回顾方法。

<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'" >
  This div is x-large.
</div>

设若要同时设置四个内联样式,NgStyle指令或者是越来越好的选料。

咱俩选用NgStyle经过绑定到二个 key:value 调控Map。对象的各个key
是样式名,它的 value 是能用于这一个样式的其它值。

设想组件方法比如setStyles,重回二个定义了二种体裁的对象:

Map<String, String> setStyles() {
  return <String, String>{
    'font-style': canSave ? 'italic' : 'normal', // italic
    'font-weight': !isUnchanged ? 'bold' : 'normal', // normal
    'font-size': isSpecial ? '24px' : '8px' // 24px
  };
}

前几天丰硕NgStyle本性绑定,让它调用setStyles,并相应地设置成分的体裁:

<div [ngStyle]="setStyles()">
  This div is italic, normal weight, and extra large (24px).
</div>

<h4 id=”if”>NgIf</h4>

因此绑定NgIf指令到真值表明式,能够把成分子树(成分及其子成分)增加到
DOM 上。

<div *ngIf="currentHero != null">Hello, {{currentHero.firstName}}</div>

别忘了ngIf后面包车型地铁星号(*)。

绑定到假值表明式将从 DOM 中移除成分子树。

<!-- because of the ngIf guard
    `nullHero.firstName` never has a chance to fail -->
<div *ngIf="nullHero != null">Hello, {{nullHero.firstName}}</div>

<!-- Hero Detail is not in the DOM because isActive is false-->
<hero-detail *ngIf="isActive"></hero-detail>

在检讨格局,Dart
期望Boolean值不是true就是false。就算在生养方式,唯有值是true才当作true;全数别的的值都以false。typescript和javascript,与之区别,把多个值(包蕴非空对象)作为true。比如,在TS版的
Angular 代码中,*ngIf="currentHero",而在Dart
*ngIf="currentHero!=null"

体制绑定

语法:[style.style-property]

<button [style.color]="isSpecial ? 'red': 'green'">Red</button>
<button [style.background-color]="canSave ? 'cyan': 'grey'" >Save</button>

富含单位的绑定:

<button [style.font-size.em]="isSpecial ? 3 : 1" >Big</button>
<button [style.font-size.%]="!isSpecial ? 150 : 50" >Small</button>

平常更爱好使用 ngStyle 指令来还要安装多少个内联样式。

可知性和NGIF不是一遍事

咱俩得以因此类绑定或样式绑定来体现和隐藏成分子树(成分及其子元素)。

<!-- isSpecial is true -->
<div [class.hidden]="!isSpecial">Show with class</div>
<div [class.hidden]="isSpecial">Hide with class</div>

<!-- HeroDetail is in the DOM but hidden -->
<hero-detail [class.hidden]="isSpecial"></hero-detail>

<div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div>
<div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div>

隐藏子树和用NgIf免去子树是完全不相同的。

当隐藏子树时,它依旧留在 DOM
中。子树中的组件及其状态照旧保留着。纵然对于不可知属性,Angular
也会连续检查退换。子树也许占用十二分可观的内部存款和储蓄器和平运动算财富。

NgIffalse时,Angular 从 DOM 中物理地移除了这么些成分子树。
它销毁了子树中的组件及其状态,也神秘释放了可观的能源,最后让用户体验到更加好的品质。

呈现 /
隐藏才能用在小型成分树上可能尚可。但在隐蔽大树时大家得小心;NgIf或许是更安全的选项。但要记住:永久得先度量,再下定论。

<h4 id=”switch”>NgSwitch</h4>

当必要从一组也许的成分树中根据规范显得二个时,大家就把它绑定到NgSwitch
Angular 将只把选中的因素树放进 DOM 中。

上面是例证:

  Eenie
  Meanie
  Miney
  Moe
  other

作者们把作为父指令的NgSwitch绑定到能回来按键值的表明式。本例中,那个值是字符串,但它也足以是此外类型的值。

那几个例子中,父指令NgSwitch调整1组子元素。每个也许挂在相称值表明式上,恐怕被标志为暗中同意情状。

其它时候,那个 span 中最多只有八个会冒出在 DOM 中

1旦这一个 span 的相称值等于按钮值,Angular 就把这些“增加到 DOM
中。 假诺未有此外 span 匹配上,Angular 就把默许的 span 增添到 DOM 中。
Angular 会移除并销毁全数其余的 span。

能够用别的别的成分取代本例中的
span。那多少个元素得以是带有巨大子树的<div>。唯有相称的<div>和它的子树会彰显在
DOM 中,此外的则会被移除。

此间有多个相互同盟的命令:

  1. ngSwitch:绑定到再次来到按键值的表明式
  2. ngSwitchCase:绑定到重临相配值的表明式
  3. ngSwitchDefault:用于标识出暗中认可成分的 attribute

不要在ngSwitch的目前加星号 (*),而应当用属性绑定
要把星号 (*) 放在ngSwitchCasengSwitchDefault的前面

<h4 id=”for”>NgFor</h4>

NgFor是1个重复器指令——自定义数据展现的1种方法。

咱俩的对象是显得贰个由多少个条约组成的列表。首先定义了一个 HTML
块,它规定了单个条目款项应该如何呈现。再告诉 Angular
把那个块当做模板,渲染列表中的每个条目款项。

下例中,NgFor应用在四个简便的<div>上:

<div *ngFor="let hero of heroes">{{hero.fullName}}</div>

也足以把NgFor行使在三个组件元素上,就下例那样:

<hero-detail *ngFor="let hero of heroes" [hero]="hero"></hero-detail>

赋值给*ngFor的文件是用来引导重复器如何是好事的吩咐。

事件绑定 (伊夫nt binding) (event)

语法:(目标事件)=”模版语句”
(target event)=”template statement”

<button (click)="onSave()">Save</button>

NgFor 微语法

赋值给*ngFor的字符串不是模板表明式。它是多个微语法 —— 由 Angular
本身解释的微型语言。在这一个事例中,字符串"let hero of heroes"的意义是:

取出heroes列表中的每一种英雄,把它存入局部变量hero中,并在历次迭代时对模板
HTML 可用

Angular 把那些命令翻译成一组成分和绑定。

在前面包车型客车多少个例证中,ngFor指令在heroes列表上开始展览迭代(它是由父组件的heroes属性重返的),以其所在的成分为模板“冲压”出不少实例。Angular
为数组中的各样英雄创造了此模板的二个全新实例。

hero前面的let器重字创造了号称hero的模版输入变量。

模板输入变量和模板引用变量不是3次事!

在模板中接纳那几个变量来做客豪杰的性能,就如在插值表明式中所做的那么。也得以把这一个变量传给组件成分上的绑定,就像对hero-detail所做的那样。

对象事件

要素事件可能是更广阔的对象,但 Angular
会先看这一个名字是还是不是能相配春季知指令的风浪性质,如:

<!-- `myClick` is an event on the custom `ClickDirective` -->
<div (myClick)="clickMessage=$event" clickable>click with myClick</div>

要是这么些名字没能相称到成分事件或已知指令的出口属性,Angular
就能够报“未知指令”错误。

带索引的 NgFor

ngFor指令帮忙可选的index,它在迭代经过中会从 0
增进到“数组的长短”。能够由此沙盘输入变量来捕获这几个
index,并在模板中动用。

下例把 index 捕获到名称为i的变量中,使用它“冲压出”像 “1 – Hercules Son
of Zeus” 这样的条款。

<div *ngFor="let hero of heroes; let i=index">{{i + 1}} - {{hero.fullName}}</div>

要读书越来越多的类似 index 的值,举个例子lastevenodd,请参阅 NgFor
API
参考

$event 和事件管理语句(event handling statements)

在事件绑定中,Angular
会为目的事件设置事件管理器。当事件爆发时,这么些管理器会实践模板语句。规范的沙盘语句经常涉及到响应事件施行动作的接收器,比如从
HTML 控件中获得值,并存入模型。
In an event binding, Angular sets up an event handler for the target
event. When the event is raised, the handler executes the template
statement. The template statement typically involves a receiver, which
performs an action in response to the event, such as storing a value
from the HTML control into a model.

绑定会由此名为 $event 的轩然大波目的传递关于此事件的音信(包蕴数据值)。

事件目的的形象取决于目标事件。
The shape of the event object is determined by the target event.

假设目标事件是原生 DOM 成分事件, $event 就是
DOM事件目标,它有像
targettarget.value 那样的属性。

<input [value]="currentHero.name"
       (input)="currentHero.name=$event.target.value" >

一经事件属于指令,那么 $event 具体是何等由指令决定。

NgForTrackBy

ngFor命令有时候会性能较差,尤其是在大型列表中。对1个条约的壹丁点改变、移除或丰裕,都会导致级联的
DOM 操作。

举个例子,大家得以经过重复从服务器询问来刷新英雄列表。刷新后的列表只怕含有众多(如若不是任何的话)从前展现过的大胆。

笔者们驾驭那一点,是因为每一种英雄的id未曾变动。但在 Angular
看来,它只是三个由新的对象引用构成的新列表,它从不选取,只可以清理旧列表、扬弃这一个DOM 成分,并且用新的 DOM 成分来重建1个新列表。

假使给它三个追踪函数,Angular 就足以免止那种折腾。追踪函数告诉
Angular:大家领略七个具有同等hero.id的靶子实际是同多少个义无返顾。
上边便是那样一个函数:

int trackByHeroes(int index, Hero hero) => hero.id;

现在,把NgForTrackBy一声令下设置为杰出跟踪函数。

<div *ngFor="let hero of heroes; trackBy:trackByHeroes">({{hero.id}}) {{hero.fullName}}</div>
<div *ngFor="let hero of heroes" *ngForTrackBy="trackByHeroes">({{hero.id}}) {{hero.fullName}}</div>

追踪函数不会堵住全部 DOM 改动。倘若同2个勇猛的属性别变化化了,Angular
就恐怕不得不更新DOM成分。可是只要那天性子未有变化——而且超过一半时候它们不会生成——Angular
就会留住这么些 DOM 元素。列表分界面就能够愈加平缓,提供更加好的响应。

<h3 id=”star”>* 与 <template></h3>

当审视NgForNgIfNgSwitch这几个内置指令时,我们接纳了一种诡异的语法:出现在命令名称后面包车型客车星号
(*)。

*是1种语法糖,它让那多少个要求注重模板来修改 HTML 布局的一声令下更便于读写。
NgFor、NgIfNgSwitch都会加上或移除成分子树,那几个成分子树棉被服装进在<template>标签中。

大家尚无看到<template>标签,那是因为那种*前缀语法让我们忽略了那个标签,而把集中力平素聚焦在所要包罗、排除或另行的这几个HTML 成分上。

那一节,将深远钻研一下,看看 Angular 是何等扒掉那些*,把这段 HTML
展开到<template>标签中的。

选择 伊夫ntEmitter 完成自定义事件

普通,指令使用
EventEmitter
来触发自定义事件。指令创设三个 EventEmitter
实例,并且把它作为品质暴流露来。指令调用 EventEmitter.emit(payload)
来触发事件,能够流传任何事物作为音信载荷。
父指令通过绑定到那个性格来监听事件,并由此 $event 对象来走访载荷。

展开*ngIf

咱俩得以像 Angular 同样,本人把*前缀语法张开成 template
语法,这里是*ngIf的片段代码:

<hero-detail *ngIf="currentHero != null" [hero]="currentHero"></hero-detail>

currentHero被引用了一遍,第3遍是当做NgIf的真/假条件,第3次把实际的
hero 值传给了HeroDetailComponent

开始展览的首先步是把ngIf(没有*前缀)和它的源委传给表达式,再赋值给template指令。

<hero-detail template="ngIf:currentHero != null" [hero]="currentHero"></hero-detail>

下一步,也是终极一步,是把 HTML
包裹进<template>标签和[ngIf]属性绑定中:

<template [ngIf]="currentHero != null">
  <hero-detail [hero]="currentHero"></hero-detail>
</template>

注意,[hero]="currengHero"绑定留在了 template
中的子成分<hero-detail>上。

不要误写为ngIf="currentHero"!这种语法会把二个字符串"currentHero"赋值给ngIf。因为ngIf盼望3个bool,所以它不会职业。

示例

假设 HeroDetailComponent 用于浮现好汉的音讯,并响应用户的动作。 固然
HeroDetailComponent 包涵删除按键,但它本身并不知道该怎么着删除这么些硬汉。
最棒的做法是接触事件来报告“删除用户”的乞请。

src/app/hero-detail.component.ts (template)

template: `
<div>
  ![]({{heroImageUrl}})

    {{prefix}} {{hero?.name}}

  <button (click)="delete()">Delete</button>
</div>`

src/app/hero-detail.component.ts (deleteRequest)

// This component make a request but it can't actually delete a hero.
deleteRequest = new EventEmitter<Hero>();

delete() {
  this.deleteRequest.emit(this.hero);
}

注明:组件定义了 deleteRequest 属性,它是 EventEmitter 实例。
当用户点击删除时,组件会调用 delete() 方法,让 EventEmitter
发出三个 Hero 对象。

现行反革命,倘使有个宿主的父组件,它绑定了 HeroDetailComponent
deleteRequest 事件。

<hero-detail (deleteRequest)="deleteHero($event)" [hero]="currentHero"></hero-detail>

deleteRequest 事件触发时,Angular 调用父组件的 deleteHero 方法,
$event 变量中传唱要去除的身先士卒(来自 HeroDetail)。

展开*ngSwitch

看似的调换也适用于*ngSwitch。大家得以谐和度开这一个语法糖。下例中,首先是*ngSwitchCase*ngSwitchDefault,然后再解出<template>标签:

      <!-- with *NgSwitch -->
      Eenie
      Meanie
      Miney
      Moe
      other

      <!-- with <template> -->
      <template [ngSwitchWhen]="'Eenie'">Eenie</template>
      <template [ngSwitchWhen]="'Meanie'">Meanie</template>
      <template [ngSwitchWhen]="'Miney'">Miney</template>
      <template [ngSwitchWhen]="'Moe'">Moe</template>
      <template ngSwitchDefault>other</template>

*ngSwitchCase
*ngSwitchDefault用和*ngIf完全同样的办法举办,把它们以前的要素包裹在<template>标签中。

前些天,应该精晓为何ngSwitch自个儿不能够用星号 (*)
前缀了吗?它未有定义内容,它的行事是调节一组模板。

地点那种景色下,它管理两组NgSwitchCaseNgSwitchDefault一声令下。大家也目的在于它显示所选模板的值一回,三次是
(*) 前缀的版本,二回是拓展模板后的本子。那便是在那几个事例中来看的.

模板语句有副功用

模板语句的副作用不仅仅没问题,反而正是所期望的。

展开*ngFor

*ngFor也经历近乎的改换。从三个*ngFor的例证初始:

<hero-detail *ngFor="let hero of heroes; trackBy:trackByHeroes" [hero]="hero"></hero-detail>

那边是在把ngFor传进template命令后的同3个事例:

<hero-detail template="ngFor let hero of heroes; trackBy:trackByHeroes" [hero]="hero"></hero-detail>

上边,它被进一步扩充成了包装着原来<hero-detail>元素的<template>标签:

<template ngFor let-hero [ngForOf]="heroes" [ngForTrackBy]="trackByHeroes">
  <hero-detail [hero]="hero"></hero-detail>
</template>

NgFor的代码绝对NgIf更复杂一点,因为重复器有更加多活动有的要求配置。那种气象下,我们就得记住增加NgForOf指令和NgForTrackBy命令,并对它们赋值。使用*ngFor语法比从来写那个进展后的
HTML 本人要简单多了。

<h三 id=”var”>模板引用变量</h叁>

模板引用变量是模板中对 DOM 成分或指令的引用。

它能在原生 DOM 成分中选拔,也能用来 Angular
组件——实际上,它能够和其余自定义 Web 组件协同专业。

双向数据绑定 (Two-way binding) [(...)]

语法:[(x)]

[(x)] 语法结合了品质绑定的方括号 [x] 和事件绑定的圆括号
(x)。当3个因素具备足以设置的属性 x 和对应的轩然大波 xChange
时,就足以行使 [(x)] 语法 。

示例 src/app/sizer.component.ts

import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
  selector: 'my-sizer',
  template: `
  <div>
    <button (click)="dec()" title="smaller">-</button>
    <button (click)="inc()" title="bigger">+</button>
    <label [style.font-size.px]="size">FontSize: {{size}}px</label>
  </div>`
})
export class SizerComponent {
  @Input()  size: number | string;
  @Output() sizeChange = new EventEmitter<number>();
  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);
  }
}

AppComponent.fontSize 被双向绑定到 SizerComponent

<my-sizer [(size)]="fontSizePx"></my-sizer>
<div [style.font-size.px]="fontSizePx">Resizable Text</div>

Angular 将 SizerComponent 的绑定分解成这样:

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

说明:$event 变量包涵了 SizerComponent.sizeChange 事件的荷载。
当用户点击按键时,Angular 将 $event 赋值给
AppComponent.fontSizePx

引用模板引用变量

咱们得以在目前模板的别的地方引用模板引用变量。

无须在同贰个模板中屡屡概念同样变量名,不然运转时的值将会不可预测。

此地是有关创制和应用模板引用变量的其它三个例子:

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

<!-- fax refers to the input element; pass its `value` to an event handler -->
<input ref-fax placeholder="fax number">
<button (click)="callFax(fax.value)">Fax</button>

“phone” 的 (#) 前缀表示定义了多少个phone变量。

多少人不欣赏使用#字符,而是使用它的标准格局:ref-前缀。例如,既能用#phone,也能用ref-phone来定义phone变量。

置于指令

怎么样获得变量的值

Angular
把那种变量的值设置为它所在的丰硕成分。在这几个input要素上定义了那几个变量。把那几个input要素对象传给
button 成分,在事变绑定中,它们作为参数字传送给了call方法。

停放属性型指令(Built-in attribute directives)

属性型指令会监听和退换其余 HTML 成分或机件的行为、成分 Attribute、DOM
Property。 它们平常会作为 HTML Attribute 的名目而利用在要素上。

广阔的放开属性型指令:

  • NgClass 增多或移除1组CSS类
  • NgStyle 增添或移除1组CSS样式
  • NgModel 双向绑定到 HTML 表单元素

NgForm 和模板引用变量

让大家看看最终八个事例:表单,使用模板引用变量的范例。

正如在表单1章中所见过的,表单的 HTML 能够做得卓越复杂。
上面是简化过的典范——即便仍算不上多不难。

<form (ngSubmit)="onSubmit(theForm)" #theForm="ngForm">
  <div class="form-group">
    <label for="name">Name</label>
    <input class="form-control" required ngControl="firstName"
      [(ngModel)]="currentHero.firstName">
  </div>
  <button type="submit" [disabled]="!theForm.form.valid">Submit</button>
</form>

模板引用变量theForm在这几个事例中出现了贰回,中间隔着第一次全国代表大会段 HTML。

<form (ngSubmit)="onSubmit(theForm)" #theForm="ngForm">
  <button type="submit" [disabled]="!theForm.form.valid">Submit</button>
</form>

theForm变量的值是什么样?

1经 Angular
未有接管它,那它大概是个HTMLFormElement。实际上它是个ngForm,对
Angular
内置指令NgForm的引用。它包裹了原生的HTMLFormElement并赋予它越多超本领,比方盯住用户输入的实用。

那表达了该怎么通过检查theForm.form.valid来剥夺提交开关,以及怎么着把贰个信息量略大的对象传给父组件的onSubmit办法。(译注:onSubmit方法或然会出发事件,被父组件监听,参见下边包车型地铁输入和出口属性和父组件监听子组件的事件。)

<h三 id=”ipt”>输入与输出属性</h三>

迄今,大家第二聚集在绑定注脚的左边,学习怎样在模板表明式和模板语句中绑定到零部件成员。当成员出现在这几个地方上,则称之为数据绑定的

本节则在意于绑定到的目标,它坐落绑定表明中的左边。这么些指令的天性必须被声称成输入输出

记住:负有组件皆为命令

咱俩要首要非凡下绑定目标和绑定的区别。

绑定的靶子是在=左侧的一些,源则是在=右边手的有个别。

绑定的目的是绑定符:[]()[()]中的属性或事件名,源则是引号
(" ") 中的部分或插值符号 ({ {} }) 中的部分。

指令中的每种成员都会自行在绑定中可用。无需特地做哪些,就能够在模板表明式或语句中走访指令的分子。

访问目标指令中的成员则遭到限制。只好绑定到这么些显式标志为输入输出的属性。

在底下的例子中,iconUrlonSave是组件的成员,它们在=右侧引号语法中被引述了。

<img [src]="iconUrl"/>
<button (click)="onSave()">Save</button>

它们既不是组件的输入也不是出口。它们是绑定的数据源。

现在,看看HeroDetailComponent,它是绑定的目的

<hero-detail [hero]="currentHero" (deleteRequest)="deleteHero($event)">
</hero-detail>

HeroDetailComponent.heroHeroDetailComponent.deleteRequest都在绑定评释的左侧

HeroDetailComponent.hero在方括号中,它是性质绑定的靶子。HeroDetailComponent.deleteRequest在圆括号中,它是事件绑定的靶子。

NgClass

示范:组件方法 setCurrentClasses 能够把组件的属性 currentClasses
设置为二个目标,它将会基于多少个其余组件的意况为 truefalse
而加多或移除三个类。

currentClasses: {};
setCurrentClasses() {
  // CSS classes: added/removed per current state of component properties
  this.currentClasses =  {
    saveable: this.canSave,
    modified: !this.isUnchanged,
    special:  this.isSpecial
  };
}

ngClass 属性绑定到 currentClasses,根据它来安装此因素的 CSS 类:

<div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special</div>

你既能够在初步化时调用
setCurrentClassess(),也得以在所依据的习性别变化化时调用。

扬言输入和出口属性

目的属性必须被显式的暗号为输入或输出。

当大家深远HeroDetailComponent其中时,就能够看到那么些属性被讲解标识成了输入和出口属性。

@Input() Hero hero;
@Output() final deleteRequest = new EventEmitter<Hero>();

除此以外,还是能在指令元数据的inputsoutputs列表中标志出那一个成员。举个例子这些例子:

 @Component(
   // ...
   inputs: const ['hero'],
   outputs: const ['deleteRequest'],
  )

既能够透过注脚,也能够透过元数据列表来钦定输入/输出属性。但别同时用!

NgStyle

ngStyle 须要绑定到2个 key:value 调节目的。 对象的各样 key
是样式名,它的 value 是能用于那几个样式的此外值。

currentStyles: {};
setCurrentStyles() {
  // CSS styles: set per current state of component properties
  this.currentStyles = {
    'font-style':  this.canSave      ? 'italic' : 'normal',
    'font-weight': !this.isUnchanged ? 'bold'   : 'normal',
    'font-size':   this.isSpecial    ? '24px'   : '12px'
  };
}

<div [ngStyle]="currentStyles">
  This div is initially italic, normal weight, and extra large (24px).
</div>

输入依然输出?

输入属性凉时接收数据值。输出属性暴光事件生产者,如·伊芙ntEmitter·对象。

输入和出口这七个词是从目标指令的角度来讲的。

4858美高梅 20

HeroDetailComponent角度来看,HeroDetailComponent.hero是个输入品质,因为数量流从模板绑定表明式流入那些属性。

HeroDetailComponent角度来看,HeroDetailComponent.deleteRequest是个输出属性,因为事件从这么些属性流出,流向模板绑定语句中的管理器。

NgModel

要使用 ngModel 必要导入 FormsModule 模块。

示例:

import { NgModule } from '@angular/core';
import { BrowserModule }  from '@angular/platform-browser';
import { FormsModule } from '@angular/forms'; // <--- JavaScript import from Angular

/* Other imports */

@NgModule({
  imports: [
    BrowserModule,
    FormsModule  // <--- import into the NgModule
  ],
  /* Other module metadata */
})
export class AppModule { }

越多关于 FormsModulengModel
的开始和结果参见表单。

使用 ngModel 达成双向数据绑定。

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

该语句实在隐藏了其落成细节:

<input [ngModel]="currentHero.name"
       (ngModelChange)="currentHero.name=$event">

如果要求做一些不1的拍卖,就不能够选用 [(ngModel)]
语法,而应写成扩充的不二秘诀:

<input [ngModel]="currentHero.name"
       (ngModelChange)="setUppercaseName($event)">

ngModel 指令只可以用在支撑
ControlValueAccessor
的要素上。

给输入/输出属性起小名

突发性供给让输入/输出属性的公开名字不相同于内部名字。

那是选用 attribute
指令时的大面积情状。指令的使用者期望绑定到指令名。比方,在<div>上用myClick选拔器应用指令时,希望绑定的风浪性质也叫myClick

<div (myClick)="clickMessage=$event">click with myClick</div>

但是,在指令类中,直接用指令名作为自个儿的性质名普通都不是好的挑三拣四。指令名很少能描述那特特性是干嘛的。myClick那一个指令名对于用来发生click 音信的习性即使不上2个好名字。

碰巧的是,能够行使约定俗成的公然名字,同时在在那之中采取分裂的名字。
在上头例子中,实际上是把myClick其一别称指向了指令自身的clicks属性。

把外号传进@Input/@Output评释,就能够为属性钦定外号,如同那样:

// @Output(alias) [type info] propertyName = ...
@Output('myClick') final EventEmitter clicks = new EventEmitter<String>();

也可在inputsoutputs列表中为属性内定外号。能够写3个冒号 (:)
分隔的字符串,左边是指令中的属性名,右边则是当面包车型大巴别名。

@Directive(
    // ...
    outputs: const ['clicks:myClick']) // propertyName:alias

<h3 id=”opt”>模板表明式操作符</h叁>

模板表明式语言应用了 Dart
语法的子集,并补充了多少个用于特定情景的异样操作符。上面介绍当中的多少个:管道安全导航操作符

<h四 id=”pip”>管道操作符 (|)</h4>

在绑定在此以前,表明式的结果只怕须要有的调换。比方,大概希望把数显成金额、强制文本产生大写,只怕过滤列表以及举办排序。

Angular
管道对像这么的微型转变到说是个明智的选拔。管道是3个总结的函数,它承受三个输入值,并重返调换结果。它们很轻易用于模板表明式中,只要采取管道操作符
(|)
就行了。

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

管道操作符会把它左边的表明式结果传给它左侧的管道函数。

还是能通过三个管道串联表明式:

<!-- Pipe chaining: convert title to uppercase, then to lowercase -->
<div>
  Title through a pipe chain:
  { {title | uppercase | lowercase} }
</div>

还能够对它们利用参数:

<!-- pipe with configuration argument => "February 25, 1970" -->
<div>Birthdate: { {currentHero?.birthdate | date:'longDate'} }</div>

<h4 id=”safe”>安全导航操作符 (?.) 和空属性路线</h4>

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

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

平安导航操作符(?.)是 Dart
语言的一片段。它被感到是二个模板表明式操作符,因为 Angular 援救 ?.
即便是在Typescript和javascript应用。

大家来详细阐释一下以此主题材料和平解决决方案:

假设下列数据绑定中title属性为空,会发生哪些?

The title is {{title}}

以此视图如故被渲染出来,然则来得的值是空;只好见到 “The title
is”,它背后却并未有别的事物。那是理之当然的一颦一笑。至少应用尚未崩溃。

壹经模板说明式涉及属性路线,在下例中,显示七个空 (null)
豪杰的firstName

The null hero's name is {{nullHero.firstName}}

Dart 抛出了空引用错误,Angular 也是这样:

EXCEPTION: The null object does not have a getter 'firstName'.

更不佳的是,整个视图都突然消失了。

即使确信hero质量永久不或者为空,能够声称那是客观的一言一动。即使它必须无法为空,但它照旧是空值,实际上是创设了多少个编程错误,它应该被破获和修补。那种情景应当抛出万分。

3头,属性路线中的空值大概会时不时发生,越发是当我们领略数码最后相会世。

当等待数据的时候,视图渲染器不应该抱怨,而应当把那么些空属性路线突显为空白,就好像上边title属性那样。

不好的是,当currentHero为空的时候,应用崩溃了。

能够由此写NgIf代码来缓和这几个主题材料。

<!--No hero, div not displayed, no error -->
<div *ngIf="nullHero != null">The null hero's name is {{nullHero.firstName}}</div>

那么些点子都有价值,可是会显得笨重,尤其是当以此天性路线非常短的时候。想象一下在3个十分长的天性路线(如a.b.c.d)中对空值提供爱慕。

Angular 安全导航操作符 (?.)
是在品质路线中保证空值的愈发通畅、便利的不二等秘书诀。
表达式会在它遭遇第3个空值的时候跳出。彰显是空的,但使用符合规律专门的职业,而尚未产生错误。

<!-- No hero, no problem! -->
The null hero's name is {{nullHero?.firstName}}

在像a?.b?.c?.d诸如此类的长属性路线中,它工作得很完美。

嵌入结构型指令(Built-in structural directives)

结构型指令担当 HTML 布局。

广阔的内置结构型指令:

  • NgIf conditionally add or remove an element from the DOM
  • NgFor repeat a template for each item in a list
  • NgSwitch a set of directives that switch among alternative views

总结

我们做到了模版语法的概述。现在,该把什么写组件和指令的知识投入到实际专门的学问当中了。

NgIf

You can add or remove an element from the DOM by applying an NgIf
directive to that element (called the host elment).

示例:

<hero-detail *ngIf="isActive"></hero-detail>

When the isActive expression returns a truthy value, NgIf adds the
HeroDetailComponent to the DOM. When the expression is falsy, NgIf
removes the HeroDetailComponent from the DOM, destroying that
component and all of its sub-components.

别忘了 ngIf 前边的星号( * )。

那和展现/隐藏不是二次事。

咱俩也能够通过类绑定或样式绑定来体现或隐匿多少个要素。但隐藏子树和用
NgIf 排除子树是完全分裂的。

当隐藏子树时,它依旧留在 DOM 中。当 NgIffalse 时 Angular 从 DOM
中物理地移除了子树,它销毁了子树中的组件及其状态,也神秘释放了惊人的财富。

严防空指针错误

NgIf 指令常常会用来防护空指针错误。 而展现/隐藏的章程是心有余而力不足堤防的。

<div *ngIf="currentHero">Hello, {{currentHero.name}}</div>
<div *ngIf="nullHero">Hello, {{nullHero.name}}</div>

currentHero 的名字唯有当存在 currentHero 时才会显得出来。 而
nullHero 恒久不会议及展览示。

NgFor

NgFor 是三个重复器指令——展现列表项的一种方式。你先定义了三个 HTML
块,它规定了单个条约应该怎么着显示。然后您告知 Angular
把那个块当做模板,渲染列表中的各种条目款项。
NgFor is a repeater directive — a way to present a list of items. You
define a block of HTML that defines how a single item should be
displayed. You tell Angular to use that block as a template for
rendering each item in the list.

例子1:

<div *ngFor="let hero of heroes">{{hero.name}}</div>

例子2:

<hero-detail *ngFor="let hero of heroes" [hero]="hero"></hero-detail>

别忘了 ngFor 前面包车型客车星号( * )。

赋值给 *ngFor 的字符串不是模板表明式,它是贰个微语法 —— 由 Angular
自个儿解释的袖珍语言。

字符串 "let hero of heroes" 的含义:

取出 heroes 数组中的种种大侠,把它存入局地变量 hero
中,并在历次迭代时对模板 HTML 可用。
Take each hero in the heroes array, store it in the local hero looping
variable, and make it available to the templated HTML for each
iteration.

模板输入变量 (Template input variables)

The let keyword before hero creates a template input variable
called hero.

*ngFor 的索引 (index)

The index property of the NgFor directive context returns the
zero-based index of the item in each iteration.

<div *ngFor="let hero of heroes; let i=index">{{i + 1}} - {{hero.name}}</div>

更多内容参见 NgFor
API

*ngFor with trackBy

ngFor
指令有时候会质量较差,尤其是在大型列表中。对3个条条框框的1丁点退换、移除或加多,都会导致级联的
DOM 操作。

有了 trackBy4858美高梅 ,,则只有 id 发生变动才会触发成分替换。

在组件中增添方法:

trackByHeroes(index: number, hero: Hero): number { return hero.id; }

使用 trackBy

<div *ngFor="let hero of heroes; trackBy: trackByHeroes">
  ({{hero.id}}) {{hero.name}}
</div>

NgSwitch

NgSwitch can display one element from among several possible elements,
based on a switch condition.

NgSwitch 由多个指令组成:

  • 属性型指令 NgSwitch
  • 结构型指令 NgSwitchCase
  • 结构型指令 NgSwitchDefault

示例:

<div [ngSwitch]="currentHero.emotion">
  <happy-hero    *ngSwitchCase="'happy'"    [hero]="currentHero"></happy-hero>
  <sad-hero      *ngSwitchCase="'sad'"      [hero]="currentHero"></sad-hero>
  <confused-hero *ngSwitchCase="'confused'" [hero]="currentHero"></confused-hero>
  <unknown-hero  *ngSwitchDefault           [hero]="currentHero"></unknown-hero>
</div>

NgSwitch 指令在增添或移除组件成分 (component elements) 时更加有用。

模板引用变量 (Template reference variables) #var

模板引用变量平常是四个模板中的对 DOM 元素的一个引用。
A template reference variable is often a reference to a DOM element
within a template.

应用井号 # (或 ref-)来声称三个模板引用变量。The#phone declares a
phone variable on an <input> element.

<input #phone placeholder="phone number">
或者写成
<input ref-phone placeholder="phone number">

你能够在模板中的任性地方引用该模板引用变量。

<input #phone placeholder="phone number">

<!-- lots of other elements -->

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

说明:phone refers to the phone number <input> box. The phone
button click handler passes the *input *value to the component’s
callPhone method.

模板引用变量如何赢得自己的值?

普通,假若2个因素申明了三个模板引用变量,那么 Angular
会将模板引用变量的值设置为该因素的值。
In most cases, Angular sets the reference variable’s value to the
element on which it was declared.

示例:

<form (ngSubmit)="onSubmit(heroForm)" #heroForm="ngForm">
  <div class="form-group">
    <label for="name">Name
      <input class="form-control" name="name" required [(ngModel)]="hero.name">
    </label>
  </div>
  <button type="submit" [disabled]="!heroForm.form.valid">Submit</button>
</form>
<div [hidden]="!heroForm.form.valid">
  {{submitMessage}}
</div>

If Angular hadn’t taken it over when you imported the FormsModule, it
would be the
HTMLFormElement.
The heroForm
is actually a reference to an Angular
NgForm
directive with the ability to track the value and validity of every
control in the form.

The native <form> element doesn’t have a form property. But the
NgForm directive does, which explains how you can disable the submit
button if the heroForm.form.valid is invalid and pass the entire form
control tree to the parent component’s onSubmit method.

注意

模板引用变量 (template reference variable) (#phone) 与模板输入变量
(template input variable) (*ngFor 中的 let phone)
并区别。详见结构型指令。

输入输出属性 @Input@Output

绑定目的与绑定源的分别:

  • 绑定的目标是在 = 左侧的部分, 则是在 =
    右侧的部分。
  • 绑定的目标是绑定符:[]()[()] 中的属性或事件名,
    源则是引号 " " 中的部分或插值符号 {{}} 中的部分。
  • 命令中的每一种成员都会活动在绑定中可用。
    无需专门做哪些,就会在模板表明式或语句中访问指令的成员。
  • 访问目标一声令下中的成员则惨遭限制
    只可以绑定到那么些显式标识为输入输出的属性。

iconUrlonSave 是绑定源

<img [src]="iconUrl"/>
<button (click)="onSave()">Save</button>

HeroDetailComponent.hero 是性质绑定的对象。
HeroDetailComponent.deleteRequest 是事件绑定的靶子。

<hero-detail [hero]="currentHero" (deleteRequest)="deleteHero($event)">
</hero-detail>

声称输入和输出属性

对象属性必须被显式的号子为输入或输出。

主意一:使用装饰器 @Input()@Output()

@Input()  hero: Hero;
@Output() deleteRequest = new EventEmitter<Hero>();

艺术二:通过元数据数组。

@Component({
  inputs: ['hero'],
  outputs: ['deleteRequest'],
})

两种办法不可同时利用。

输入还是输出?

输入属性经常接收数据值。 输出属性揭穿事件生产者。
Input properties usually receive data values. Output properties expose
event producers.

输入和输出那八个词是从目标指令的角度来讲的。

  • HeroDetailComponent 角度来看,HeroDetailComponent.hero
    是个输入属性, 因为数量流从模板绑定表明式流入那几个属性。
  • HeroDetailComponent
    角度来看,HeroDetailComponent.deleteRequest 是个出口属性,
    因为事件从这2个属性流出,流向模板绑定语句中的管理器。

给输入输出属性起小名

方法一:把外号传进 @Input / @Output 装饰器,就能够为属性内定别称:

@Output('myClick') clicks = new EventEmitter<string>(); //  @Output(alias) propertyName = ...

方法2:在 inputsoutputs 数组中为属性钦定小名。
语法(属性名:小名)。

@Directive({
  outputs: ['clicks:myClick']  // propertyName:alias
})

模板表达式操作符

管道操作符 |

管道是1个简易的函数,它承受3个输入值,并重回转变结果。

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

管道操作符会把它右边的表达式结果传给它左边的管道函数。

越多内容见管道。

还足以由此八个管道串联表明式:

<!-- Pipe chaining: convert title to uppercase, then to lowercase -->
<div>
  Title through a pipe chain:
  {{title | uppercase | lowercase}}
</div>

仍是能够对管道使用参数:

<!-- pipe with configuration argument => "February 25, 1970" -->
<div>Birthdate: {{currentHero?.birthdate | date:'longDate'}}</div>

json 管道对调养绑定越发实用:

<div>{{currentHero | json}}</div>

输出结果:

{ "id": 0, "name": "Hercules", "emotion": "happy",
  "birthdate": "1970-02-25T08:00:00.000Z",
  "url": "http://www.imdb.com/title/tt0065832/",
  "rate": 325 }

六盘水导航操作符 ( ?. ) 和空属性路径

Angular 的平安导航操作符 (?.) 用来维护出现在性质路线中 null 和 undefined
值。示例:

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

说明:当 currentHero 为空时,敬重视图渲染器,让它免于败北。

来得三个空 (null) 铁汉的 name 示例:

The null hero's name is {{nullHero.name}}

:marked
  JavaScript throws a null reference error, and so does Angular:
JavaScript 抛出了空引用错误,Angular 也是如此:code-example(format="nocode").
  TypeError: Cannot read property 'name' of null in [null].

currentHero 为空的时候,应用崩溃了,整个视图都遗落了。

笨重的消除办法一:

<!--No hero, div not displayed, no error -->
<div *ngIf="nullHero">The null hero's name is {{nullHero.name}}</div>

笨重的化解办法二:

The null hero's name is {{nullHero && nullHero.name}}

是的的解决办法:

<!-- No hero, no problem! -->
The null hero's name is {{nullHero?.name}}

总结

痛快淋漓掌握模板语法对开拓首要。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有