我们希望用户能够采取行动,并导致页面上发生一些事情。用户会在输入框中输入文字,从列表中挑选项目,并点击按钮。这些类型的用户行为会导致数据从一个元素流向一个组件。对某些事件的监听,如击键、鼠标移动和点击,是通过Angular事件绑定完成的。用户可能采取的最常见的行动是一个点击事件。一些常见的JavaScript事件包括onclick、onmouseover、onmouseout、onchange、onkeydown、onkeyup,以及更多。我们可以在Angular中使用一个特殊的语法来设置一个点击事件。
(click)="methodToRun()"
在virtual-machines.component.html Angular模板中,如果你想响应一个点击事件,你可以使用这种形式的绑定。
<button
[disabled]="!allowNewVm"
class="btn btn-lg"
(click)="onCreateVM()"
>Add a VM</button>
(click)说,"嘿,我们正在监听用户的点击"。标记的="onCreateVM() "部分说,"当点击时运行这一段代码"。
配置.ts文件来响应
在我们的模板中,我们现在已经设置了一个点击事件监听器。当它被点击时,我们希望有事情发生。为了设置这个,首先我们将创建一个新的变量来保存数据的初始状态。这将是 vmCreated我们在virtual-machines.component.ts中看到的变量。
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-virtual-machines',
templateUrl: './virtual-machines.component.html',
styleUrls: ['./virtual-machines.component.css'],
})
export class VirtualMachinesComponent implements OnInit {
allowNewVm = false;
vmCreated = 'Initial State: Add a VM?';
constructor() {
setTimeout(() => {
this.allowNewVm = true
}, 1500);
}
ngOnInit() {
}
}
除了新的变量,我们还需要新的方法或函数,它应该在按钮被点击时运行。我们在模板中把这个函数命名为onCreateVM。这意味着我们将像这样把这个命名的函数添加到TypeScript文件中。
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-virtual-machines',
templateUrl: './virtual-machines.component.html',
styleUrls: ['./virtual-machines.component.css'],
})
export class VirtualMachinesComponent implements OnInit {
allowNewVm = false;
vmCreated = 'Initial State: Add a VM?';
constructor() {
setTimeout(() => {
this.allowNewVm = true
}, 1500);
}
ngOnInit() {
}
onCreateVM() {
this.vmCreated = 'Button Clicked: New VM spun up!';
}
}
引用模板中的数据
最后,我们通过字符串插值输出vmCreated变量的内容。在页面加载时,它应该输出该变量的初始值。当用户点击按钮时,该值应发生变化,这也将实时更新用户界面。
<button [disabled]="!allowNewVm" class="btn btn-lg" (click)="onCreateVM()">Add a VM</button>
the allowNewVm variable is currently <b [innerText]="allowNewVm"></b>
<hr>
<h5>{{ vmCreated }}</h5>
<app-virtual-machine></app-virtual-machine>
在浏览器中检查的结果给了我们这个预期的结果。最初,页面加载时显示存储在vmCreated变量中的字符串。然后,我们点击按钮,我们的函数onCreateVM就会运行。这就改变了存储在vmCreated变量中的数据,页面就会实时更新以反映这一情况。在Angular中,有很多方法可以对用户的输入做出反应,这只是一个对按钮点击做出反应的例子。
(input)="onMethodToRun($event)"
说到用户输入,让我们设置一个字段,允许用户在创建虚拟机之前为其提供一个名称。这 $event很特别。它就像一个保留的变量名,你可以在事件绑定时在模板中使用。它是一种在事件发生时从该输入中获取数据的方法。所以这就是我们如何为这个测试设置virtual-machines.component.html模板。
<form>
<div class="form-group">
<label for="vmname">VM Name</label>
<input type="text" class="form-control" (input)="onSetVmName($event)" id="vmname">
<small class="form-text text-muted">Enter the name for a new VM.</small>
</div>
</form>
<p>Add the <b>{{ vmName }}</b> virtual machine?</p>
<button [disabled]="!allowNewVm" class="btn btn-lg" (click)="onCreateVM()">Add a VM</button>
the allowNewVm variable is currently <b [innerText]="allowNewVm"></b>
<hr>
<h5>{{ vmCreated }}</h5>
<app-virtual-machine></app-virtual-machine>
现在我们可以在 **onSetVmName**方法中接受这些数据。
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-virtual-machines',
templateUrl: './virtual-machines.component.html',
styleUrls: ['./virtual-machines.component.css'],
})
export class VirtualMachinesComponent implements OnInit {
allowNewVm = false;
vmCreated = 'Initial State: Add a VM?';
vmName = '';
constructor() {
setTimeout(() => {
this.allowNewVm = true
}, 1500);
}
ngOnInit() {
}
onCreateVM() {
this.vmCreated = 'Button Clicked: New VM spun up!';
}
onSetVmName(event) {
this.vmName = event.target.value;
}
}
通过这个,我们可以看到,我们确实在捕捉输入到的数据。
双向数据绑定
在上面的代码中,我们有点走了很长的路来设置数据绑定。一个更简单的方法是简单地使用 **[(ngModel)]**指令。
<form>
<div class="form-group">
<label for="vmname">VM Name</label>
<input
type="text"
class="form-control"
[(ngModel)]="vmName"
name="vmName"
id="vmname"
>
<small class="form-text text-muted">Enter the name for a new VM.</small>
</div>
</form>
<p>Add the <b>{{ vmName }}</b> virtual machine?</p>
<button [disabled]="!allowNewVm" class="btn btn-lg" (click)="onCreateVM()">Add a VM</button>
the allowNewVm variable is currently <b [innerText]="allowNewVm"></b>
<hr>
<h5>{{ vmCreated }}</h5>
<app-virtual-machine></app-virtual-machine>
你会注意到,我们还使用name="vmName "来设置名称属性。这样做的原因是,如果你不设置它,你可能会看到类似 "ERROR错误。如果ngModel在表单标签中使用,必须设置name属性或者在ngModelOptions中把formcontrol定义为'独立'。"
使用[(ngModel)]="vmName "测试了数据绑定,似乎效果不错。还要注意的是,我们不再需要virtual-machines.component.ts中的onSetVmName(event)方法,因为ngModel正在为我们自动处理这个问题。
把它放在一起
在这个阶段,我们希望能够输入输入,但不是让它马上显示在屏幕上。我们将捕获这些数据,但只有在用户点击按钮后才将其输出到屏幕上。要做到这一点,我们可以更新onCreateVM()方法,以便像这样利用捕获的数据。
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-virtual-machines',
templateUrl: './virtual-machines.component.html',
styleUrls: ['./virtual-machines.component.css'],
})
export class VirtualMachinesComponent implements OnInit {
allowNewVm = false;
vmCreated = 'Initial State: Add a VM?';
vmName = '';
constructor() {
setTimeout(() => {
this.allowNewVm = true
}, 1500);
}
ngOnInit() {
}
onCreateVM() {
this.vmCreated = 'Button Clicked: New *' + this.vmName + '* VM spun up!';
}
}
这样我们就得到了最终的结果,看起来像这样。