sự kiện nhấp chuột kích hoạt thủ công angle2 trên phần tử cụ thể


81

Tôi đang cố gắng kích hoạt sự kiện nhấp chuột (hoặc bất kỳ sự kiện nào khác) trên phần tử theo chương trình, Nói cách khác, tôi muốn biết các tính năng tương tự như được cung cấp bởi phương thức jQuery .trigger () trong angle2.

Có bất kỳ phương pháp tích hợp để làm điều này? ..... nếu không, xin vui lòng đề nghị làm thế nào tôi có thể làm điều này

Xem xét đoạn mã sau

<form [ngFormModel]="imgUploadFrm"
          (ngSubmit)="onSubmit(imgUploadFrm)">
        <br>
        <div class="input-field">
            <input type="file" id="imgFile" (click)="onChange($event)" >
        </div>
        <button id="btnAdd" type="submit" (click)="showImageBrowseDlg()" )>Add Picture</button>
 </form>

Ở đây khi người dùng nhấp vào btnAdd, nó sẽ kích hoạt sự kiện nhấp chuột trên imgFile


Bạn chỉ cần imgFile.click()thay vì showImageBrowseDlg()nếu bạn làm theo dưới đây câu trả lời của @ Akshay-khale stackoverflow.com/a/41675017/344029 (sau khi thêm biến <input #imgFile)
DJDaveMark

Câu trả lời:


182

Angular4

Thay vì

    this.renderer.invokeElementMethod(
        this.fileInput.nativeElement, 'dispatchEvent', [event]);

sử dụng

    this.fileInput.nativeElement.dispatchEvent(event);

invokeElementMethodsẽ không còn là một phần của trình kết xuất nữa.

Angular2

Sử dụng ViewChild với biến mẫu để nhận tham chiếu đến đầu vào tệp, sau đó sử dụng Trình kết xuất để gọi dispatchEventkích hoạt sự kiện:

import { Component, Renderer, ElementRef, ViewChild } from '@angular/core';
@Component({
  ...
  template: `
...
<input #fileInput type="file" id="imgFile" (click)="onChange($event)" >
...`
})
class MyComponent {
  @ViewChild('fileInput') fileInput:ElementRef;

  constructor(private renderer:Renderer) {}

  showImageBrowseDlg() {
    // from http://stackoverflow.com/a/32010791/217408
    let event = new MouseEvent('click', {bubbles: true});
    this.renderer.invokeElementMethod(
        this.fileInput.nativeElement, 'dispatchEvent', [event]);
  }
}

Cập nhật

Vì quyền truy cập DOM trực tiếp không được nhóm Angular khuyến khích nữa nên mã đơn giản hơn này cũng có thể được sử dụng

this.fileInput.nativeElement.click()

Xem thêm https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent


10
this.fileInput.nativeElement.click()có vẻ như cũng hoạt động.
lbrahim

3
@lbrahim đúng rồi. Vào thời điểm đó, đó là một gợi ý mạnh mẽ để tránh truy cập các thuộc tính hoặc phương thức nativeElementvà sử dụng Rendererthay thế. Tôi nghĩ điều này đã thay đổi một chút gần đây và truy cập DOM trực tiếp hiện đã ổn nhưng nó sẽ không hoạt động với kết xuất phía máy chủ và WebWorkers.
Günter Zöchbauer

1
@AralRoca sau đó sử dụng @ViewChildren('fileInput') QueryList<ElementRef>;Xem thêm stackoverflow.com/questions/32693061/…
Günter Zöchbauer

1
Tôi không hoàn toàn chắc chắn về điều đó và tôi chưa thấy tài liệu chính thức đề cập đến nó, nhưng theo như tôi nhớ thì nó đã được đề cập trong một số vấn đề GitHub. Tôi cũng nghĩ rằng hãy nhớ rằng một số ví dụ tài liệu đã được cập nhật để loại bỏ trình kết xuất và sử dụng quyền truy cập DOM trực tiếp. Tôi có ấn tượng nếu bạn không có ý định sử dụng kết xuất phía máy chủ hoặc nhân viên web, thì đó chỉ là một hạn chế rườm rà và khá nhiều nhà phát triển không quan tâm đến điều đó và đây là cách họ loại bỏ việc làm quy tắc mạnh mẽ.
Günter Zöchbauer

1
@ManuChadha tại sao lại sử dụng jquery? Nó có thể dẫn đến các vấn đề khi Angular và jquery nghĩ rằng cả hai đều nằm trong phạm vi đầy đủ của FOM. jquery gần đây đã trở nên ít liên quan hơn nhiều vì sự khác biệt giữa các trình duyệt ít hơn nhiều và hầu hết hỗ trợ cho các trình duyệt cũ đã bị loại bỏ hoàn toàn.
Günter Zöchbauer

27

Tôi cũng muốn có chức năng tương tự trong đó tôi có Điều khiển nhập tệp với display:noneđiều khiển Nút nơi tôi muốn kích hoạt sự kiện nhấp của Điều khiển nhập tệp khi tôi nhấp vào nút, dưới đây là mã để làm như vậy

<input type="button" (click)="fileInput.click()" class="btn btn-primary" value="Add From File">
<input type="file" style="display:none;" #fileInput/>

đơn giản như vậy và nó hoạt động hoàn hảo ...


1
Tôi sử dụng một cách chính xác này để bấm một nút sau khi nhấn Enter trong một lĩnh vực văn bản:<input #name type="text" (keyup.enter)="addBtn.click()"> <button #addBtn (click)="add(name.value)" type="button">Add</button>
DJDaveMark

4

Điều này đã làm việc cho tôi:

<button #loginButton ...

và bên trong bộ điều khiển:

@ViewChild('loginButton') loginButton;
...
this.loginButton.getNativeElement().click();

cảm ơn cậu. nó hoạt động như một sự quyến rũ với ionic3. :)
DwlRathod

điều này không hoạt động trên Angular 7+
davejoem

2

Câu trả lời của Günter Zöchbauer là đúng. Chỉ cần xem xét thêm dòng sau:

showImageBrowseDlg() {
    // from http://stackoverflow.com/a/32010791/217408
    let event = new MouseEvent('click', {bubbles: true});
    event.stopPropagation();
    this.renderer.invokeElementMethod(
        this.fileInput.nativeElement, 'dispatchEvent', [event]);
  }

Trong trường hợp của tôi, tôi sẽ gặp lỗi "Lỗi RangeError: Đã vượt quá kích thước ngăn xếp cuộc gọi tối đa" nếu không. (Tôi có thẻ div kích hoạt khi nhấp chuột và tệp đầu vào bên trong)


1
Bạn cũng có thể thiết lập các "bong bóng" chìa khóa để sai, giúp ngăn chặn sự kiện từ bọt lên cây dom
ChicoDelaBarrio

2

Nếu bạn muốn bắt chước, hãy nhấp vào phần tử DOM như thế này:

<a (click)="showLogin($event)">login</a>

và có một cái gì đó như thế này trên trang:

<li ngbDropdown>
    <a ngbDropdownToggle id="login-menu">
        ...
    </a>
 </li>

chức năng của bạn trong component.tsphải như thế này:

showLogin(event) {
   event.stopPropagation();
   document.getElementById('login-menu').click();
}

0

Để nhận tham chiếu gốc đến một cái gì đó như an ion-input, ry bằng cách sử dụng

@ViewChild('fileInput', { read: ElementRef }) fileInput: ElementRef;

và sau đó

this.fileInput.nativeElement.querySelector('input').click()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.