99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

Angular9 用戶(hù)輸入

2020-06-30 18:01 更新

用戶(hù)輸入

當(dāng)用戶(hù)點(diǎn)擊鏈接、按下按鈕或者輸入文字時(shí),這些用戶(hù)動(dòng)作都會(huì)產(chǎn)生 DOM 事件。 本章解釋如何使用 Angular 事件綁定語(yǔ)法把這些事件綁定到事件處理器。

綁定到用戶(hù)輸入事件

你可以使用 Angular 事件綁定機(jī)制來(lái)響應(yīng)任何 DOM 事件。 許多 DOM 事件是由用戶(hù)輸入觸發(fā)的。綁定這些事件可以獲取用戶(hù)輸入。

要綁定 DOM 事件,只要把 DOM 事件的名字包裹在圓括號(hào)中,然后用放在引號(hào)中的模板語(yǔ)句對(duì)它賦值就可以了。

下例展示了一個(gè)事件綁定,它實(shí)現(xiàn)了一個(gè)點(diǎn)擊事件處理器:

Path:"src/app/click-me.component.ts"

<button (click)="onClickMe()">Click me!</button>

等號(hào)左邊的 (click) 表示把按鈕的點(diǎn)擊事件作為綁定目標(biāo)。 等號(hào)右邊引號(hào)中的文本是模板語(yǔ)句,通過(guò)調(diào)用組件的 onClickMe 方法來(lái)響應(yīng)這個(gè)點(diǎn)擊事件。

寫(xiě)綁定時(shí),需要知道模板語(yǔ)句的執(zhí)行上下文。 出現(xiàn)在模板語(yǔ)句中的每個(gè)標(biāo)識(shí)符都屬于特定的上下文對(duì)象。 這個(gè)對(duì)象通常都是控制此模板的 Angular 組件。 上例中只顯示了一行 HTML,那段 HTML 片段屬于下面這個(gè)組件:

Path:"src/app/click-me.component.ts"

@Component({
  selector: 'app-click-me',
  template: `
    <button (click)="onClickMe()">Click me!</button>
    {{clickMessage}}`
})
export class ClickMeComponent {
  clickMessage = '';


  onClickMe() {
    this.clickMessage = 'You are my hero!';
  }
}

當(dāng)用戶(hù)點(diǎn)擊按鈕時(shí),Angular 調(diào)用 ClickMeComponentonClickMe 方法。

通過(guò) $event 對(duì)象取得用戶(hù)輸入

DOM 事件可以攜帶可能對(duì)組件有用的信息。 本節(jié)將展示如何綁定輸入框的 keyup 事件,在每個(gè)敲擊鍵盤(pán)時(shí)獲取用戶(hù)輸入。

下面的代碼監(jiān)聽(tīng) keyup 事件,并將整個(gè)事件載荷 ($event) 傳給組件的事件處理器。

Path:"src/app/keyup.components.ts (template v.1)"

template: `
  <input (keyup)="onKey($event)">
  <p>{{values}}</p>
`

當(dāng)用戶(hù)按下并釋放一個(gè)按鍵時(shí),觸發(fā) keyup 事件,Angular 在 $event 變量提供一個(gè)相應(yīng)的 DOM 事件對(duì)象,上面的代碼將它作為參數(shù)傳給 onKey() 方法。

Path:"src/app/keyup.components.ts (class v.1)"

export class KeyUpComponent_v1 {
  values = '';


  onKey(event: any) { // without type info
    this.values += event.target.value + ' | ';
  }
}

$event 對(duì)象的屬性取決于 DOM 事件的類(lèi)型。例如,鼠標(biāo)事件與輸入框編輯事件包含了不同的信息。

所有標(biāo)準(zhǔn) DOM 事件對(duì)象都有一個(gè) target 屬性, 引用觸發(fā)該事件的元素。 在本例中,target 是 <input> 元素, event.target.value 返回該元素的當(dāng)前內(nèi)容。

在組件的 onKey() 方法中,把輸入框的值和分隔符 (|) 追加組件的 values 屬性。 使用插值來(lái)把存放累加結(jié)果的 values 屬性回顯到屏幕上。

假設(shè)用戶(hù)輸入字母“abc”,然后用退格鍵一個(gè)一個(gè)刪除它們。 用戶(hù)界面將顯示:

a | ab | abc | ab | a | |

或者,你可以用 event.key 替代 event.target.value,積累各個(gè)按鍵本身,這樣同樣的用戶(hù)輸入可以產(chǎn)生:

&
a | b | c | backspace | backspace | backspace |

$event的類(lèi)型

上例將 $event 轉(zhuǎn)換為 any 類(lèi)型。 這樣簡(jiǎn)化了代碼,但是有成本。 沒(méi)有任何類(lèi)型信息能夠揭示事件對(duì)象的屬性,防止簡(jiǎn)單的錯(cuò)誤。

下面的例子,使用了帶類(lèi)型方法:

Path:"src/app/keyup.components.ts (class v.1 - typed )"

export class KeyUpComponent_v1 {
  values = '';




  onKey(event: KeyboardEvent) { // with type info
    this.values += (event.target as HTMLInputElement).value + ' | ';
  }
}

$event 的類(lèi)型現(xiàn)在是 KeyboardEvent。 不是所有的元素都有 value 屬性,所以它將 target 轉(zhuǎn)換為輸入元素。 OnKey 方法更加清晰地表達(dá)了它期望從模板得到什么,以及它是如何解析事件的。

傳入 $event 是靠不住的做法

類(lèi)型化事件對(duì)象揭露了重要的一點(diǎn),即反對(duì)把整個(gè) DOM 事件傳到方法中,因?yàn)檫@樣組件會(huì)知道太多模板的信息。 只有當(dāng)它知道更多它本不應(yīng)了解的 HTML 實(shí)現(xiàn)細(xì)節(jié)時(shí),它才能提取信息。 這就違反了模板(用戶(hù)看到的)和組件(應(yīng)用如何處理用戶(hù)數(shù)據(jù))之間的分離關(guān)注原則。

下面將介紹如何用模板引用變量來(lái)解決這個(gè)問(wèn)題。

從一個(gè)模板引用變量中獲得用戶(hù)輸入

還有另一種獲取用戶(hù)數(shù)據(jù)的方式:使用 Angular 的模板引用變量。 這些變量提供了從模塊中直接訪(fǎng)問(wèn)元素的能力。 在標(biāo)識(shí)符前加上井號(hào) (#) 就能聲明一個(gè)模板引用變量。

下面的例子使用了局部模板變量,在一個(gè)超簡(jiǎn)單的模板中實(shí)現(xiàn)按鍵反饋功能。

Path:"src/app/loop-back.component.ts"

@Component({
  selector: 'app-loop-back',
  template: `
    <input #box (keyup)="0">
    <p>{{box.value}}</p>
  `
})
export class LoopbackComponent { }

這個(gè)模板引用變量名叫 box,在 <input> 元素聲明,它引用 <input> 元素本身。 代碼使用 box 獲得輸入元素的 value 值,并通過(guò)插值把它顯示在 <p> 標(biāo)簽中。

這個(gè)模板完全是完全自包含的。它沒(méi)有綁定到組件,組件也沒(méi)做任何事情。

在輸入框中輸入,就會(huì)看到每次按鍵時(shí),顯示也隨之更新了。

除非你綁定一個(gè)事件,否則這將完全無(wú)法工作。

只有在應(yīng)用做了些異步事件(如擊鍵),Angular 才更新綁定(并最終影響到屏幕)。 本例代碼將 keyup 事件綁定到了數(shù)字 0,這可能是最短的模板語(yǔ)句了。 雖然這個(gè)語(yǔ)句不做什么,但它滿(mǎn)足 Angular 的要求,所以 Angular 將更新屏幕。

從模板變量獲得輸入框比通過(guò) $event 對(duì)象更加簡(jiǎn)單。 下面的代碼重寫(xiě)了之前 keyup 示例,它使用變量來(lái)獲得用戶(hù)輸入。

Path:"src/app/keyup.components.ts (v2)"

@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 + ' | ';
  }
}

這個(gè)方法最漂亮的一點(diǎn)是:組件代碼從視圖中獲得了干凈的數(shù)據(jù)值。再也不用了解 $event 變量及其結(jié)構(gòu)了。

按鍵事件過(guò)濾(通過(guò) key.enter)

(keyup) 事件處理器監(jiān)聽(tīng)每一次按鍵。 有時(shí)只在意回車(chē)鍵,因?yàn)樗鼧?biāo)志著用戶(hù)結(jié)束輸入。 解決這個(gè)問(wèn)題的一種方法是檢查每個(gè) $event.keyCode,只有鍵值是回車(chē)鍵時(shí)才采取行動(dòng)。

更簡(jiǎn)單的方法是:綁定到 Angular 的 keyup.enter 模擬事件。 然后,只有當(dāng)用戶(hù)敲回車(chē)鍵時(shí),Angular 才會(huì)調(diào)用事件處理器。

Path:"src/app/keyup.components.ts (v3)"

@Component({
  selector: 'app-key-up3',
  template: `
    <input #box (keyup.enter)="onEnter(box.value)">
    <p>{{value}}</p>
  `
})
export class KeyUpComponent_v3 {
  value = '';
  onEnter(value: string) { this.value = value; }
}

下面展示了它的工作原理。

失去焦點(diǎn)事件 (blur)

前上例中,如果用戶(hù)沒(méi)有先按回車(chē)鍵,而是移開(kāi)了鼠標(biāo),點(diǎn)擊了頁(yè)面中其它地方,輸入框的當(dāng)前值就會(huì)丟失。 只有當(dāng)用戶(hù)按下了回車(chē)鍵候,組件的 values屬性才能更新。

下面通過(guò)同時(shí)監(jiān)聽(tīng)輸入框的回車(chē)鍵和失去焦點(diǎn)事件來(lái)修正這個(gè)問(wèn)題。

Path:"src/app/keyup.components.ts (v4)"

@Component({
  selector: 'app-key-up4',
  template: `
    <input #box
      (keyup.enter)="update(box.value)"
      (blur)="update(box.value)">


    <p>{{value}}</p>
  `
})
export class KeyUpComponent_v4 {
  value = '';
  update(value: string) { this.value = value; }
}

結(jié)合使用

現(xiàn)在,在一個(gè)微型應(yīng)用中一起使用它們,應(yīng)用能顯示一個(gè)英雄列表,并把新的英雄加到列表中。 用戶(hù)可以通過(guò)輸入英雄名和點(diǎn)擊“添加”按鈕來(lái)添加英雄。

下面就是“簡(jiǎn)版英雄指南”組件。

Path:"src/app/little-tour.component.ts"

@Component({
  selector: 'app-little-tour',
  template: `
    <input #newHero
      (keyup.enter)="addHero(newHero.value)"
      (blur)="addHero(newHero.value); newHero.value='' ">


    <button (click)="addHero(newHero.value)">Add</button>


    <ul><li *ngFor="let hero of heroes">{{hero}}</li></ul>
  `
})
export class LittleTourComponent {
  heroes = ['Windstorm', 'Bombasto', 'Magneta', 'Tornado'];
  addHero(newHero: string) {
    if (newHero) {
      this.heroes.push(newHero);
    }
  }
}

源代碼

  1. Path:"src/app/click-me.component.ts"

    import { Component } from '@angular/core';


    @Component({
      selector: 'app-click-me',
      template: `
        <button (click)="onClickMe()">Click me!</button>
        {{clickMessage}}`
    })
    export class ClickMeComponent {
      clickMessage = '';


      onClickMe() {
        this.clickMessage = 'You are my hero!';
      }
    }

  1. Path:"src/app/keyup.components.ts"

    import { Component } from '@angular/core';


    @Component({
      selector: 'app-key-up1',
      template: `
        <input (keyup)="onKey($event)">
        <p>{{values}}</p>
      `
    })
    export class KeyUpComponent_v1 {
      values = '';


      /*
      onKey(event: any) { // without type info
        this.values += event.target.value + ' | ';
      }
      */


      onKey(event: KeyboardEvent) { // with type info
        this.values += (event.target as HTMLInputElement).value + ' | ';
      }
    }


    //////////////////////////////////////////


    @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 + ' | ';
      }
    }


    //////////////////////////////////////////


    @Component({
      selector: 'app-key-up3',
      template: `
        <input #box (keyup.enter)="onEnter(box.value)">
        <p>{{value}}</p>
      `
    })
    export class KeyUpComponent_v3 {
      value = '';
      onEnter(value: string) { this.value = value; }
    }


    //////////////////////////////////////////


    @Component({
      selector: 'app-key-up4',
      template: `
        <input #box
          (keyup.enter)="update(box.value)"
          (blur)="update(box.value)">


        <p>{{value}}</p>
      `
    })
    export class KeyUpComponent_v4 {
      value = '';
      update(value: string) { this.value = value; }
    }

  1. Path:"src/app/loop-back.component.ts"

    import { Component } from '@angular/core';
    @Component({
      selector: 'app-loop-back',
      template: `
        <input #box (keyup)="0">
        <p>{{box.value}}</p>
      `
    })
    export class LoopbackComponent { }

  1. Path:"src/app/little-tour.component.ts"

    import { Component } from '@angular/core';


    @Component({
      selector: 'app-little-tour',
      template: `
        <input #newHero
          (keyup.enter)="addHero(newHero.value)"
          (blur)="addHero(newHero.value); newHero.value='' ">


        <button (click)="addHero(newHero.value)">Add</button>


        <ul><li *ngFor="let hero of heroes">{{hero}}</li></ul>
      `
    })
    export class LittleTourComponent {
      heroes = ['Windstorm', 'Bombasto', 'Magneta', 'Tornado'];
      addHero(newHero: string) {
        if (newHero) {
          this.heroes.push(newHero);
        }
      }
    }

Angular 還支持被動(dòng)事件偵聽(tīng)器。例如,你可以使用以下步驟使?jié)L動(dòng)事件變?yōu)楸粍?dòng)監(jiān)聽(tīng)。

  1. 在 src 目錄下創(chuàng)建一個(gè) "zone-flags.ts" 文件。

  1. 往這個(gè)文件中添加如下語(yǔ)句。

(window as any)['__zone_symbol__PASSIVE_EVENTS'] = ['scroll'];

  1. 在 "src/polyfills.ts" 文件中,導(dǎo)入 "zone.js" 之前,先導(dǎo)入新創(chuàng)建的 "zone-flags" 文件。

import './zone-flags';
import 'zone.js/dist/zone';  // Included with Angular CLI.

經(jīng)過(guò)這些步驟,你添加 scroll 事件的監(jiān)聽(tīng)器時(shí),它就是被動(dòng)(passive)的。

小結(jié)

  • 使用模板變量來(lái)引用元素 — newHero 模板變量引用了 <input> 元素。 你可以在 <input> 的任何兄弟或子級(jí)元素中引用 newHero。

  • 傳遞數(shù)值,而非元素 — 獲取輸入框的值并將它傳給組件的 addHero,而不要傳遞 newHero。

  • 保持模板語(yǔ)句簡(jiǎn)單 — (blur) 事件被綁定到兩個(gè) JavaScript 語(yǔ)句。 第一句調(diào)用 addHero。第二句 newHero.value='' 在添加新英雄到列表中后清除輸入框。
以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)