【2020-01-23】组件与模板 -- 模板语法

绑定语法

1、从数据源到视图 

{{expression}} 

[target] = "expression" 

bind-target = "expression"

2、从视图到数据源的单向绑定

(target)= "statement"

on-target = "statement"

3、双向

[(target)] = "expression"

bindon-target = "expression"

HTML attribute  DOM property

--attribute值不能改变,但是property的值可以改变

<input type="text" value="Bob">

创建DOM节点,且它的value的property被初始化为Bob

当用户输入“sal”,Dom元素的property变成了sal,但是该HTML的attribute仍是Bob保持不变

disabled 是HTML的attribute,其property值默认是false,当添加这个disabled attribute时,disabled的property会自动初始化为true

所以禁用或者启动按钮,与attribute的值无关

<button [disabled]="isUnchanged">Save</button>

这里设置的是disabled的property值

模板绑定是通过property和事件来工作的,而不是attribute

4、绑定目标

数据绑定的目标是DOM中的某些东西,这个目标可能是元素|组件|指令的 property/事件等

①属性

 ②事件

 ③双向

 ④Attribute

 ⑤CSS类

 ⑥样式

 属性绑定

[属性名]  -- 最常用的属性绑定就是把元素属性设置为组件属性的值

属性名是property的名字 或者已知指令的属性名

当名字没有匹配上已知指令或元素的属性,Angular就会报告“未知指令”的错误

一次性字符串优化

当满足下列条件时,应该省略括号:

1、目标属性接受字符串值

2、字符串是个固定值,可以直接合并到模板中

3、这个初始值永不改变

 prefix属性值满足上面条件,所以可以省略方括号

当数据类型是字符串,可以用数据绑定[],也可以用插值{{}}

当数据类型不是字符串,只能用数据绑定[]

attribute,class, style绑定

1、attribute 绑定

当元素没有属性(property)可绑的时候,就必须使用attribute绑定

<tr><td colspan="{{1 + 1}}">Three-Four</td></tr>    //会报错,因为colspan不属于property,但插值和数据绑定只能设置property,所以需要attribute来创建和绑定这样的attribute

<tr><td [attr.colspan]="1 + 1">Three-Four</td></tr>

2、CSS类绑定 -- 添加或者移除class 属性

①直接绑定

 ②使用数据绑定 : 

  // test属性的值会覆盖原本设置的 bad curly special  , class属性最终为test属性的值

③绑定到特定的类名,当模板表达式的求值结果为真,则Angular会添加这个类

此绑定方式不会影响原来已有的class名

// 若是有多个class名,则一般通过[NgClass]管理

 3、样式绑定

通过样式绑定,可以设置内联样式

  isSpecial 和canSave都是组件属性

有些样式绑定中的样式带有单位

 

// 若是设置多个内联样式,可以用[NgStyle]指令

事件绑定

事件绑定允许你侦听某些事件,比如按键,鼠标移动,点击和触屏

目标事件

 如果这个名字没有匹配到元素事件或者已知指令的输出属性,Angular则会报“未知指令”错误

$ event 和事件处理语句

当事件发生时,这个处理器会执行模板语句。典型的模板语句通常涉及到响应事件执行动作的接收器,例如从HTML控件中取得值,并存入模型。

绑定会通过名叫$event的事件对象传递关于此事件的信息(包括数据)

事件对象的形态取决于目标事件,如果目标事件是原生DOM元素事件,$event 就是DOM事件对象,他有像target和target.value这样的属性

 上面case中,把输入框的value属性绑定到name属性,要监听对值的修改,代码绑定到输入框的input事件。当用户造成更改时,input事件被触发,并在包含了DOM事件对象($event)的上下文中执行这条语句

要更新name属性,就要通过$event.target.value来获取更改后的值

使用EventEmitter实现自定义事件

通常指令使用angular EventEmitter来触发自定义事件。指令创建一个EventEmitter 实例,并且把它作为属性暴露出来。指令调用EvenetEmitter.emit(payload)来触发事件,可以传入任何东西作为消息载荷

父指令通过绑定到这个属性来监听事件,并通过$event对象来访问载荷

 

 

双向绑定

1、双向绑定的基础知识:

双向绑定会做两件事:

①设置特定的元素属性

②监听元素的变更事件

angular为此提供了一种特殊的双向数据绑定语法[()] ,将属性绑定的[]与事件绑定的()组合在一起

 

 

 

内置指令

Angular提供了两种内置指令:属性型指令和结构型指令

1、内置属性型指令

属性型指令会监听并修改其他HTML元素和组件的行为、Attribute和Property.他们通常被应用在元素上,好像它们是HTML属性一样,因此得名属性型指令

常见的属性型指令如下:

NgClass -添加和删除一组CSS类型,如果只对一个CSS类操作请用类绑定

NgStyle - 添加和删除一组HTML样式,如果只对一个样式操作请用样式绑定

NgModel - 将数据双向绑定添加到HTML表单元素

2、内置结构型指令

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

常见的内置结构型指令:

NgIf - 从模板中创建或销毁子视图

NgFor - 为列表中的每个条目重复渲染一个节点

NgSwitch - 一组在备用视图之间切换的指令

注意:隐藏元素时,该元素以及后代仍保留在DOM中。这些元素的所有组件都保留在内存中,Angular会继续做变更检查。它可能会占用大量的资源,并且不必要降低性能

①NgIf工作方式有所不同。如果NgIf为false,则Angular将从DOM中删除该元素及其后代。这销毁了它们的组件,释放了资源,从而带来更好的用户体验

如果要隐藏大型组件树,请考虑使用NgIf作为显示、隐藏的更有效替代方法

NgIf另一个优点就是您可以使用它来防范空指针错误。

②带trackBy的*ngFor --可以提升性能

如果ngFor循环的数组需要改变(大量的新增或者删除元素),若是不带有trackBy,则所有的DOM元素会被重新刷新

若是带了trackBy --指定需要跟踪的对象,则只有跟踪的对象发生变化时才会刷新对应的DOM元素,提升性能

模板引用变量

模板引用变量(#var)

模板引用变量通常是对模板中DOM元素的引用。它还可以引用指令(包含组件)、元素、TemplateRef 或Web Component

使用#声明模板引用变量

模板引用变量的范围是整个模板

输入和输出属性

@Input --允许将数据从负责建输入到子组件中

注意:要监视@Input()属性的更改,OnChanges是专门设计用于具有@Input()装饰器的属性

@OutPut -- 指的是事件从组件中向外流出,属性类型是EventEmitter

使用@Input()/ @OutPut()装饰器指定别名 

 

 

 别名size2是在父组件中 【子组件指令中使用】

 

 

模板表达式中的运算符

1、管道

在准备将用于绑定之前,表达式的结果可能需要进行一些转换。例如,您可以将数组显示为货币,将文本更改为大写,或过滤列表并对其进行排序

管道是简单的函数。它们接受输入值并返回转换后的值。使用管道运算,很容易在模板表达式中使用它们

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

<p>Item json pipe: {{item | json}}</p>    // json pipe可以将json对象转为json格式的字符串

管道运算符的优先级比三元运算符(?:)高,这意味着a ? b: c | x 将被解析为

a ? b : (c | x) .

2、安全导航运算符

Angular 安全导航运算符?可以对在属性路径中出现null和undefined值进行保护

<p>The item name is: {{item?.name}}</p>

在这里,如果item为null,它可以防止视图渲染失败,即:视图仍然渲染,但显示的值仍是空白,会占据位置

3、非空断言运算符(!)

<!--No color, no error -->
<p *ngIf="item">The item's color is: {{item!.color}}</p>

内置模板函数

类型转换函数 $any()

<p>The item's undeclared best by date is: {{$any(item).bestByDate}}</p>

$any()转换函数可以和thisi联合使用,以便访问组件中未声明的成员

<p>The item's undeclared best by date is: {{$any(this).bestByDate}}</p>

 

 

//tips

JS加载包括预编译和执行两个阶段

预编译阶段会对所有var变量和function进行扫描,并将变量初始化为undefined类型,而function则被初始化为函数值

到了执行阶段,JS从上面往下面依顺序执行,遇到var变量进行赋值(因此,在赋值之前进行调用的话会出现错误的)

 

posted @ 2020-02-06 18:16  总是不停地吃吃吃  阅读(229)  评论(0编辑  收藏  举报