事件
当用户点击链接,按下按钮,输入文字时,这些动作都会触发DOM事件,本篇博客解释如何使用Angular 事件绑定语法把这些事件绑定到事件处理器。
事件绑定
Angular提供了事件绑定机制,可以响应任何DOM事件,Angular 的事件绑定语法由等号左侧带圆括号的目标事件和右侧引号中的模板语句组成。 下面事件绑定监听按钮的点击事件。每当点击发生时,都会调用组件的 onSave()
方法。
目标事件
如前所述,其目标就是此按钮的单击事件。
<button (click)="onSave($event)">Save</button>
有些人更喜欢带 on-
前缀的备选形式,称之为规范形式:
<button on-click="onSave($event)">on-click Save</button>
$event 和事件处理语句
在事件绑定中,Angular 会为目标事件设置事件处理器。
当事件发生时,这个处理器会执行模板语句。 典型的模板语句通常涉及到响应事件执行动作的接收器,例如从 HTML 控件中取得值,并存入模型。
绑定会通过名叫 $event
的事件对象传递关于此事件的信息(包括数据值)。
事件对象的形态取决于目标事件。如果目标事件是原生 DOM 元素事件, $event
就是 DOM 事件对象,它有像 target 和 target.value
这样的属性。
考虑这个范例:
<input [value]="currentItem.name"
(input)="currentItem.name=$event.target.value" >
上面的代码在把输入框的 value 属性绑定到 name 属性。 要监听对值的修改,代码绑定到输入框的 input 事件。 当用户造成更改时,input 事件被触发,并在包含了 DOM 事件对象 ($event) 的上下文中执行这条语句。
要更新 name 属性,就要通过路径 $event.target.value 来获取更改后的值。
$event 具体是什么由指令决定。
传入$event 是靠不住的做法
类型化事件对象揭露了重要的一点,即反对把整个 DOM 事件传到方法中,因为这样组件会知道太多模板的信息。 只有当它知道更多它本不应了解的 HTML 实现细节时,它才能提取信息。 这就违反了模板(用户看到的)和组件(应用如何处理用户数据)之间的分离关注原则。
下面将介绍如何用模板引用变量来解决这个问题。
从一个模板引用变量中获得用户输入
还有另一种获取用户数据的方式:使用 Angular 的模板引用变量。 这些变量提供了从模块中直接访问元素的能力。 在标识符前加上井号 (#) 就能声明一个模板引用变量。
下面的例子使用了局部模板变量,在一个超简单的模板中实现按键反馈功能。
@Component({
selector: 'app-loop-back',
template: `
<input #box (keyup)="0">
<p>{{box.value}}</p>
`
})
export class LoopbackComponent { }
这个模板引用变量名叫 box
,在 <input>
元素声明,它引用 <input>
元素本身。 代码使用 box
获得输入元素的 value
值,并通过插值表达式把它显示在 <p>
标签中。
这个模板完全是完全自包含的。它没有绑定到组件,组件也没做任何事情。
在输入框中输入,就会看到每次按键时,显示也随之更新了。
除非你绑定一个事件,否则这将完全无法工作。
只有在应用做了些异步事件(如击键),Angular 才更新绑定(并最终影响到屏幕)。 本例代码将keyup
事件绑定到了数字 0,这可能是最短的模板语句了。 虽然这个语句不做什么,但它满足 Angular 的要求,所以 Angular 将更新屏幕。
从模板变量获得输入框比通过 $event
对象更加简单。 下面的代码重写了之前 keyup
示例,它使用变量来获得用户输入。
@Component({
selector: 'app-key-up2',
template: `
<input #box (keyup)="onKey(box.value)">
<p>{{values}}</p>
`
})
export class KeyUpComponent_v2 {
values = '';
onKey(value: string) {
this.values += value + ' | ';
}
}
这个方法最漂亮的一点是:组件代码从视图中获得了干净的数据值。再也不用了解 $event 变量及其结构了。
网友评论