การจัดการเหตุการณ์ HTML5 (ออนโฟกัสและออนโฟกัส) โดยใช้เชิงมุม 2


118

ฉันมีช่องวันที่และต้องการลบตัวยึดตามค่าเริ่มต้น

ฉันใช้จาวาสคริปต์onfocusและonfocusoutเหตุการณ์เพื่อลบตัวยึด

ใครช่วยใช้คำสั่ง angular2 ได้ไหม

<input name="date" type="text" onfocus="(this.type='date')" onfocusout="(this.type='text')" class="dateinput">

ฉันพยายามแก้ไขด้วยวิธีนี้ แต่ฉันมีปัญหากับการรีเซ็ตประเภทช่องป้อนข้อมูล

import { Directive, ElementRef, Input } from 'angular2/core';
@Directive({
    selector: '.dateinput', 
    host: {
    '(focus)': 'setInputFocus()',
    '(focusout)': 'setInputFocusOut()',
  }})

  export class MyDirective {
      constructor(el: ElementRef) { this.el = el.nativeElement; console.log(this.el);}

      setInputFocus(): void {
        //console.log(this.elementRef.nativeElement.value);
      }
  }

คำตอบ:


235

พยายามใช้(focus)และ(focusout)แทนonfocusและonfocusout

แบบนี้ : -

<input name="date" type="text" (focus)="focusFunction()" (focusout)="focusOutFunction()">

คุณยังสามารถใช้สิ่งนี้: -

บางคนชอบทางเลือก on-prefix หรือที่เรียกว่ารูปแบบบัญญัติ:

<input name="date" type="text" on-focus="focusFunction()" on-focusout="focusOutFunction()">

ทราบข้อมูลเพิ่มเติมเกี่ยวกับเหตุการณ์ที่มีผลผูกพันดูที่นี่

คุณต้องใช้ HostListner สำหรับกรณีการใช้งานของคุณ

Angular จะเรียกใช้เมธอดตกแต่งเมื่อองค์ประกอบโฮสต์ปล่อยเหตุการณ์ที่ระบุ @HostListenerเป็นมัณฑนากรสำหรับเมธอด callback / event handler

ดูการปรับปรุงการทำงานของฉัน Plunker

ตัวอย่างการทำงาน Working Plunker

ปรับปรุง

เหตุการณ์อื่น ๆ สามารถใช้ในเชิงมุม -

(focus)="myMethod()"
(blur)="myMethod()" 
(submit)="myMethod()"  
(scroll)="myMethod()"

ที่คุณใช้คำสั่งของคุณชื่อdateinput?
Pardeep Jain

@vishnu ดู plnuker ที่อัปเดตของฉัน
Pardeep Jain

2
สิ่งที่ควรทราบหากคุณใช้การใช้ HTML เริ่มต้นอาจใช้ขอบเขตส่วนกลางเมื่อเรียกใช้ฟังก์ชันที่กำหนด ตัวอย่างเช่นonfocusout="someMethod()" someMethod()ในกรณีนี้จะถูกเรียกในขอบเขตทั่วโลก นั่นเป็นอีกเหตุผลหนึ่งว่าทำไมการใช้ Angular ในกรณีนี้จึงมีค่า
kbpontius

1
@ user5365075 ฉันไม่เห็นการอัปเดตดังกล่าวดูที่นี่การสาธิตfocus ng6
Pardeep Jain

2
ความผิดพลาดของฉันfocusจะใช้ได้กับอินพุตและพื้นที่ข้อความที่รองรับ แต่ถ้าคุณมีส่วนประกอบที่กำหนดเองที่ไม่รองรับคุณสามารถใช้focusinแทนได้ :)
user5365075

7

หากคุณต้องการจับเหตุการณ์โฟกัสแบบไดนามิกในทุกอินพุตบนส่วนประกอบของคุณ:

import { AfterViewInit, Component, ElementRef } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit {

  constructor(private el: ElementRef) {
  }

  ngAfterViewInit() {
       // document.getElementsByTagName('input') : to gell all Docuement imputs
       const inputList = [].slice.call((<HTMLElement>this.el.nativeElement).getElementsByTagName('input'));
        inputList.forEach((input: HTMLElement) => {
            input.addEventListener('focus', () => {
                input.setAttribute('placeholder', 'focused');
            });
            input.addEventListener('blur', () => {
                input.removeAttribute('placeholder');
            });
        });
    }
}

ตรวจสอบรหัสเต็มได้ที่นี่: https://stackblitz.com/edit/angular-93jdir


2

ฉันได้สร้างคำสั่งเล็กน้อยที่เชื่อมโยงกับแอตทริบิวต์ tabindex เพิ่ม / ลบคลาสที่มีโฟกัสแบบไดนามิก

@Directive({
    selector: "[tabindex]"
})
export class TabindexDirective {
    constructor(private elementHost: ElementRef) {}

    @HostListener("focus")
    setInputFocus(): void {
        this.elementHost.nativeElement.classList.add("has-focus");
    }

    @HostListener("blur")
    setInputFocusOut(): void {
        this.elementHost.nativeElement.classList.remove("has-focus");
    }
}

0

ทางออกคือ:

  <input (click)="focusOut()" type="text" matInput [formControl]="inputControl"
  [matAutocomplete]="auto">
   <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn" >
     <mat-option (onSelectionChange)="submitValue($event)" *ngFor="let option of 
      options | async" [value]="option">
      {{option.name | translate}}
     </mat-option>
  </mat-autocomplete>

TS
focusOut() {
this.inputControl.disable();
this.inputControl.enable();
}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.