如何在AngularJS中绑定事件

284 阅读4分钟

我们希望用户能够采取行动,并导致页面上发生一些事情。用户会在输入框中输入文字,从列表中挑选项目,并点击按钮。这些类型的用户行为会导致数据从一个元素流向一个组件。对某些事件的监听,如击键、鼠标移动和点击,是通过Angular事件绑定完成的。用户可能采取的最常见的行动是一个点击事件。一些常见的JavaScript事件包括onclickonmouseoveronmouseoutonchangeonkeydownonkeyup,以及更多。我们可以在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!';
  }

}

这样我们就得到了最终的结果,看起来像这样。