@HostBinding và @hostListener: họ làm gì và họ làm gì?


188

Trong những lần đi vòng quanh thế giới, và đặc biệt là các tài liệu theo phong cách angular.io , tôi tìm thấy nhiều tài liệu tham khảo @HostBinding@HostListener. Có vẻ như chúng khá cơ bản, nhưng thật không may, tài liệu cho chúng vào lúc này là một chút sơ sài.

Bất cứ ai có thể vui lòng giải thích những gì họ đang làm, cách họ làm việc và đưa ra một ví dụ về việc sử dụng của họ?

Câu trả lời:


139

Bạn đã kiểm tra các tài liệu chính thức?

HostListener - Khai báo một trình nghe máy chủ. Angular sẽ gọi phương thức được trang trí khi phần tử máy chủ phát ra sự kiện đã chỉ định.

@HostListener - sẽ lắng nghe sự kiện được phát ra bởi phần tử máy chủ được khai báo với @HostListener .

HostBinding - Khai báo ràng buộc thuộc tính máy chủ. Angular tự động kiểm tra các ràng buộc thuộc tính máy chủ trong quá trình phát hiện thay đổi. Nếu một ràng buộc thay đổi, nó sẽ cập nhật phần tử máy chủ của lệnh.

@HostBinding- sẽ liên kết thuộc tính với phần tử máy chủ, Nếu một ràng buộc thay đổi, HostBindingsẽ cập nhật phần tử máy chủ.


LƯU Ý: Cả hai liên kết đã được gỡ bỏ gần đây. Phần " HostBinding-HostListening " của hướng dẫn kiểu có thể là một sự thay thế hữu ích cho đến khi các liên kết trở lại.


Đây là một ví dụ mã đơn giản để giúp hình dung điều này có nghĩa là gì:

DEMO: Đây là bản demo trực tiếp trong plunker - "Một ví dụ đơn giản về @hostListener & @hostBinding"

  • Ví dụ này liên kết một thuộc roletính - được khai báo với@HostBinding - với phần tử của máy chủ
    • Hãy nhớ lại đó rolelà một thuộc tính, vì chúng tôi đang sử dụngattr.role .
    • <p myDir>trở thành <p mydir="" role="admin">khi bạn xem nó trong các công cụ phát triển.
  • Sau đó, nó lắng nghe onClicksự kiện được khai báo cùng với @HostListenerphần tử máy chủ của thành phần, thay đổirole theo từng nhấp chuột.
    • Thay đổi khi <p myDir>được nhấp là thẻ mở của nó thay đổi từ <p mydir="" role="admin">đến <p mydir="" role="guest">và quay lại.

chỉ thị

import {Component,HostListener,Directive,HostBinding,Input} from '@angular/core';

@Directive({selector: '[myDir]'})
export class HostDirective {
  @HostBinding('attr.role') role = 'admin'; 
  @HostListener('click') onClick() {
    this.role= this.role === 'admin' ? 'guest' : 'admin';
  }
}

AppComponent.ts

import { Component,ElementRef,ViewChild } from '@angular/core';
import {HostDirective} from './directives';

@Component({
selector: 'my-app',
template:
  `
  <p myDir>Host Element 
    <br><br>

    We have a (HostListener) listening to this host's <b>click event</b> declared with @HostListener

    <br><br>

    And we have a (HostBinding) binding <b>the role property</b> to host element declared with @HostBinding 
    and checking host's property binding updates.

    If any property change is found I will update it.
  </p>

  <div>View this change in the DOM of the host element by opening developer tools,
    clicking the host element in the UI. 

    The role attribute's changes will be visible in the DOM.</div> 
    `,
  directives: [HostDirective]
})
export class AppComponent {}

1
trang trí này vẫn được sử dụng có vẻ như các liên kết đã bị xóa khỏi tài liệu angular2
CommonSenseCode

1
Vâng, nó vẫn đang được sử dụng nhưng hãy để tôi xác nhận nó một lần. Tôi sẽ cập nhật cho bạn, nếu tôi có thể tìm ra điều gì khác.
micronyks

Họ đang ở trên bảng cheat: angular.io/docs/ts/latest/guide/chcoateet.html
Targaryen

1
@ Mr.PalAnswersMcFly cập nhật câu trả lời với ghi chú và liên kết. Xin lưu ý rằng tài liệu thích hợp vẫn chưa có.
micronyks

1
@MuhammadSaleh vì khó có thể nói rằng cách tính và tính toán ... nhưng chắc chắn rằng mỗi trường hợp sẽ có một người nghe riêng
micronyks

112

Một mẹo nhanh giúp tôi nhớ những gì họ làm -

HostBinding('value') myValue; hoàn toàn giống như [value]="myValue"

HostListener('click') myClick(){ } hoàn toàn giống như (click)="myClick()"


HostBindingHostListenerđược viết trong các chỉ thị và các chỉ thị khác (...)[..]được viết bên trong các mẫu (của các thành phần).


9
Ah, nó đã nhấp (ý định chơi chữ) với tôi nhờ câu trả lời này. @HostListenerlà cách để đi khi bạn không có bất cứ điều gì trên DOM cho ràng buộc sự kiện thông thường, chẳng hạn như nhập bàn phím trong trường hợp của tôi.
MrBoJangles

46

Dưới đây là một ví dụ di chuột cơ bản.

Thuộc tính mẫu của thành phần:

Bản mẫu

<!-- attention, we have the c_highlight class -->
<!-- c_highlight is the selector property value of the directive -->

<p class="c_highlight">
    Some text.
</p>

Và chỉ thị của chúng tôi

import {Component,HostListener,Directive,HostBinding} from '@angular/core';

@Directive({
    // this directive will work only if the DOM el has the c_highlight class
    selector: '.c_highlight'
 })
export class HostDirective {

  // we could pass lots of thing to the HostBinding function. 
  // like class.valid or attr.required etc.

  @HostBinding('style.backgroundColor') c_colorrr = "red"; 

  @HostListener('mouseenter') c_onEnterrr() {
   this.c_colorrr= "blue" ;
  }

  @HostListener('mouseleave') c_onLeaveee() {
   this.c_colorrr = "yellow" ;
  } 
}

28
Tôi không thấy câu trả lời được chấp nhận này là câu trả lời cho câu hỏi được hỏi. Bạn có quan tâm để cung cấp một số lời giải thích? Giống như những gì c_colorrr, c_on Entryrr (), c_onLeaveeee làm trong đoạn mã đặc biệt này?
luqo33

1
Tôi thik nó nên thay đổi màu sắc trên chuột nhập sự kiện sang màu xanh và trên sự kiện rời chuột sang màu vàng.
Michał Ziobro

Nơi nào bạn đặt chỉ thị trong đánh dấu? Có vẻ bạn sẽ đặt nó trên thẻ body, nhưng nó sẽ nằm ngoài thành phần gốc. Nếu bạn bối rối với câu trả lời này, liên kết này có thể giúp ng2.codecraft.tv/custom-directives/hostlistener-and-hostbinding
mtpultz

@mtpultz Nó ở trong lớp.
serkan

33

Một điều thú vị nữa @HostBindinglà bạn có thể kết hợp nó với @Inputnếu ràng buộc của bạn phụ thuộc trực tiếp vào đầu vào, ví dụ:

@HostBinding('class.fixed-thing')
@Input()
fixed: boolean;

1
Bạn có thể vui lòng chia sẻ ví dụ về việc sử dụng với @Input()?
Mano

Ví dụ là ngay trong câu trả lời của tôi, bạn chỉ cần viết cả hai trang trí lần lượt, thứ tự sẽ không liên quan
altschuler

1
Tôi nghĩ những gì tôi đang thiếu là làm thế nào khác với chỉ sử dụng @HostBinding. Khi nào bạn cần sử dụng @Input?
1252748

11

Một điều làm tăng thêm sự nhầm lẫn cho chủ đề này là ý tưởng của các nhà trang trí không được làm rõ ràng và khi chúng ta xem xét một cái gì đó như ...

@HostBinding('attr.something') 
get something() { 
    return this.somethingElse; 
 }

Nó hoạt động, bởi vì nó là một getaccessor . Bạn không thể sử dụng một chức năng tương đương:

@HostBinding('attr.something') 
something() { 
    return this.somethingElse; 
 }

Mặt khác, lợi ích của việc sử dụng @HostBindinglà nó đảm bảo phát hiện thay đổi được chạy khi giá trị ràng buộc thay đổi.


8

Tóm lược:

  • @HostBinding: Trình trang trí này liên kết một thuộc tính lớp với một thuộc tính của phần tử máy chủ.
  • @HostListener: Trình trang trí này liên kết một phương thức lớp với một sự kiện của phần tử máy chủ.

Thí dụ:

import { Component, HostListener, HostBinding } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `<p>This is nice text<p>`,
})
export class AppComponent  {

  @HostBinding('style.color') color; 

  @HostListener('click')
  onclick() {
    this.color =  'blue';
  }

}

Trong ví dụ trên xảy ra như sau:

  • Trình lắng nghe sự kiện được thêm vào sự kiện nhấp sẽ được kích hoạt khi sự kiện nhấp xảy ra ở bất kỳ đâu trong thành phần
  • Các colortài sản trong AppComponentlớp của chúng tôi được ràng buộc với style.colortài sản trên thành phần. Vì vậy, bất cứ khi nào colortài sản được cập nhật, style.colortài sản của thành phần của chúng tôi cũng vậy
  • Kết quả sẽ là bất cứ khi nào ai đó nhấp vào thành phần, màu sắc sẽ được cập nhật.

Sử dụng trong @Directive:

Mặc dù nó có thể được sử dụng trên thành phần, những người trang trí này thường được sử dụng trong một chỉ thị thuộc tính. Khi được sử dụng trong @Directivemáy chủ sẽ thay đổi thành phần mà lệnh được đặt. Ví dụ, hãy xem mẫu thành phần này:

<p p_Dir>some paragraph</p>

Ở đây p_Dir là một chỉ thị về <p>phần tử. Khi @HostBindinghoặc @HostListenerđược sử dụng trong lớp chỉ thị, máy chủ bây giờ sẽ tham chiếu đến <p>.


6

Lý thuyết với ít biệt ngữ

@Hostlistnening xử lý cơ bản với phần tử máy chủ nói (một nút) lắng nghe hành động của người dùng và thực hiện một chức năng nhất định nói cảnh báo ("Ahoy!") Trong khi @hostbinding là cách khác. Ở đây chúng tôi lắng nghe những thay đổi xảy ra trên nút đó trong nội bộ (Nói khi nó được nhấp vào những gì đã xảy ra với lớp) và chúng tôi sử dụng thay đổi đó để làm một cái gì đó khác, nói phát ra một màu cụ thể.

Thí dụ

Hãy nghĩ về kịch bản mà bạn muốn tạo một biểu tượng yêu thích trên một thành phần, bây giờ bạn biết rằng bạn sẽ phải biết liệu vật phẩm đó có được ưa thích với lớp của nó hay không, chúng ta cần một cách để xác định điều này. Đó chính xác là nơi @hostbinding xuất hiện.

Và nơi nào cần biết người dùng thực sự đã thực hiện hành động nào, đó là nơi @hostlistening xuất hiện


3
Điều này là khó hiểu, và tên trang trí là không chính xác.
matmancini
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.