发表于: 2019-10-28 12:51:39

1 1042


今天完成的事:angular文档的阅读

明天要完成的事:尝试写任务6 

难题:感觉自己的记忆的很多都是,模糊的不确定的而且不会使用,先看完在试着使用在使用中对其进行验证


收获:

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

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

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

如果能在像 <input> 和 <select> 这样的 HTML 元素上使用双向数据绑定就更好了。 可惜,原生 HTML 元素不遵循 x 值和 xChange 事件的模式。

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

  

语法糖:也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。


属性型指令会监听和修改其它 HTML 元素或组件的行为、元素属性(Attribute)、DOM 属性(Property)。 它们通常会作为 HTML 属性的名称而应用在元素上。

更多的细节参见属性型指令一章。 很多 NgModules,比如RouterModuleFormsModule都定义了自己的属性型指令。 本节将会介绍几个最常用的属性型指令:

  • NgClass - 添加或移除一组 CSS 类

  • NgStyle - 添加或移除一组 CSS 样式

  • NgModel - 双向绑定到 HTML 表单元素


如果要同时设置多个内联样式,NgStyle 指令可能是更好的选择。

NgStyle 需要绑定到一个 key:value 控制对象。 对象的每个 key 是样式名,它的 value 是能用于这个样式的任何值。

来看看组件的 setCurrentStyles 方法,它会根据另外三个属性的状态把组件的 currentStyles 属性设置为一个定义了三个样式的对象:



当想要同时添加或移除多个 CSS 类时,NgClass 指令可能是更好的选择。

试试把 ngClass 绑定到一个 key:value 形式的控制对象。这个对象中的每个 key 都是一个 CSS 类名,如果它的 value 是 true,这个类就会被加上,否则就会被移除。

组件方法 setCurrentClasses 可以把组件的属性 currentClasses 设置为一个对象,它将会根据三个其它组件的状态为 true 或 false 而添加或移除三个类。


NgModel - 使用[(ngModel)]双向绑定到表单元素

当开发数据输入表单时,你通常都要既显示数据属性又根据用户的更改去修改那个属性。

使用 ngModel 时需要 FormsModule

在使用 ngModel 指令进行双向数据绑定之前,你必须导入 FormsModule 并把它添加到 NgModule 的 imports 列表中。 要了解 FormsModule 和 ngModel 的更多知识,参见表单一章。

导入 FormsModule 并让 [(ngModel)] 可用的代码如下:

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 { }

回头看看 name 绑定,注意,你可以通过分别绑定到 <input> 元素的 value 属性和 input 事件来达到同样的效果。

<input [value]="currentHero.name"

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

使用独立的 ngModel 绑定优于绑定到该元素的原生属性,你可以做得更好。

你不用被迫两次引用这个数据属性,Angular 可以捕获该元素的数据属性,并且通过一个简单的声明来设置它,这样它就可以使用 [(ngModel)] 语法了。

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


内置结构型指令

结构型指令的职责是 HTML 布局。 它们塑造或重塑 DOM 的结构,这通常是通过添加、移除和操纵它们所附加到的宿主元素来实现的。

关于结构型指令的详情参见结构型指令一章,在那里你将学到:

本节是对常见结构型指令的简介:

  • NgIf - 根据条件把一个元素添加到 DOM 中或从 DOM 移除

    NgIf - conditionally add or remove an element from the DOM

  • NgSwitch 一组指令,用来在多个可选视图之间切换。

    NgSwitch - a set of directives that switch among alternative views

  • NgForOf - 对列表中的每个条目重复套用同一个模板

    NgForOf - repeat a template for each item in a list


NgIf

通过把 NgIf 指令应用到元素上(称为宿主元素),你可以往 DOM 中添加或从 DOM 中移除这个元素。 在下面的例子中,该指令绑定到了类似于 isActive 这样的条件表达式。

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


但隐藏子树和用 NgIf 排除子树是截然不同的。

当隐藏子树时,它仍然留在 DOM 中。 子树中的组件及其状态仍然保留着。 即使对于不可见属性,Angular 也会继续检查变更。 子树可能占用相当可观的内存和运算资源。

当 NgIf 为 false 时,Angular 从 DOM 中物理地移除了这个元素子树。 它销毁了子树中的组件及其状态,也潜在释放了可观的资源,最终让用户体验到更好的性能。

显示/隐藏的技术对于只有少量子元素的元素是很好用的,但要当心别试图隐藏大型组件树。相比之下,NgIf 则是个更安全的选择。

防范空指针错误

ngIf 指令通常会用来防范空指针错误。 而显示/隐藏的方式是无法防范的,当一个表达式尝试访问空值的属性时,Angular 就会抛出一个异常。

这里我们用 NgIf 来保护了两个 <div> 防范空指针错误。 currentHero 的名字只有当存在 currentHero 时才会显示出来。 而 nullHero 永远不会显示。

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



NgForOf

NgFor 是一个重复器指令 —— 自定义数据显示的一种方式。 你的目标是展示一个由多个条目组成的列表。首先定义了一个 HTML 块,它规定了单个条目应该如何显示。 再告诉 Angular 把这个块当做模板,渲染列表中的每个条目。

赋值给 *ngFor 的字符串不是模板表达式。 它是一个微语法 —— 由 Angular 自己解释的小型语言。在这个例子中,字符串 "let hero of heroes" 的含义是:

取出 heroes 数组中的每个英雄,把它存入局部变量 hero 中,并在每次迭代时对模板 HTML 可用

模板输入变量

hero 前的 let 关键字创建了一个名叫 hero 的模板输入变量。 ngFor 指令在由父组件的 heroes 属性返回的 heroes 数组上迭代,每次迭代都从数组中把当前元素赋值给 hero 变量。

你可以在 ngFor 的宿主元素(及其子元素)中引用模板输入变量 hero,从而访问该英雄的属性。

NgFor 指令上下文中的 index 属性返回一个从零开始的索引,表示当前条目在迭代中的顺序。 你可以通过模板输入变量捕获这个 index 值,并把它用在模板中。

下面这个例子把 index 捕获到了 i 变量中,并且把它显示在英雄名字的前面。


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



带 trackBy 的 *ngFor


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

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


NgSwitch 指令

NgSwitch 指令类似于 JavaScript 的 switch 语句。 它可以从多个可能的元素中根据switch 条件来显示某一个。 Angular 只会把选中的元素放进 DOM 中。

NgSwitch 实际上包括三个相互协作的指令:NgSwitchNgSwitchCase 和 NgSwitchDefault,例子如下:


NgSwitch 是主控指令,要把它绑定到一个返回候选值的表达式。 本例子中的 emotion 是个字符串,但实际上这个候选值可以是任意类型。

绑定到 [ngSwitch]。如果试图用 *ngSwitch 的形式使用它就会报错,这是因为 NgSwitch 是一个属性型指令,而不是结构型指令。 它要修改的是所在元素的行为,而不会直接接触 DOM 结构。

绑定到 *ngSwitchCase 和 *ngSwitchDefault NgSwitchCase 和 NgSwitchDefault 指令都是结构型指令,因为它们会从 DOM 中添加或移除元素。

  • NgSwitchCase 会在它绑定到的值等于候选值时,把它所在的元素加入到 DOM 中。

  • NgSwitchDefault 会在没有任何一个 NgSwitchCase 被选中时把它所在的元素加入 DOM 中。

这组指令在要添加或移除组件元素时会非常有用。 这个例子会在 hero-switch.components.ts 中定义的四个“感人英雄”组件之间选择。 每个组件都有一个输入属性hero,它绑定到父组件的 currentHero 上。

这组指令在原生元素和Web Component上都可以正常工作。


模板引用变量 ( #var )

模板引用变量通常用来引用模板中的某个 DOM 元素,它还可以引用 Angular 组件或指令或Web Component

使用井号 (#) 来声明引用变量。 #phone 的意思就是声明一个名叫 phone 的变量来引用 <input> 元素。

你可以在模板中的任何地方引用模板引用变量。 比如声明在 <input> 上的 phone 变量就是在模板另一侧的 <button> 上使用的。


返回列表 返回列表
评论

    分享到