@HostBinding และ @HostListener: พวกเขาทำอะไรและมีไว้เพื่ออะไร


188

ในหากินของฉันรอบ interweb ทั่วโลกและตอนนี้โดยเฉพาะอย่างยิ่งเอกสารสไตล์ angular.ioผมพบหลายอ้างอิงถึงและ@HostBinding @HostListenerดูเหมือนว่าพวกเขาจะค่อนข้างพื้นฐาน แต่น่าเสียดายที่เอกสารสำหรับพวกเขาในขณะนี้เป็นร่างเล็ก ๆ น้อย ๆ

ใครช่วยอธิบายสิ่งที่พวกเขาทำงานและยกตัวอย่างการใช้งานได้บ้าง?

คำตอบ:


139

คุณตรวจสอบเอกสารอย่างเป็นทางการเหล่านี้แล้วหรือยัง

HostListener - ประกาศฟังโฮสต์ เชิงมุมจะเรียกใช้วิธีการตกแต่งเมื่อองค์ประกอบโฮสต์ส่งเสียงเหตุการณ์ที่ระบุ

@HostListener- จะฟังเหตุการณ์ที่ปล่อยออกมาโดยองค์ประกอบโฮสต์ที่ประกาศ@HostListenerไว้

HostBinding - ประกาศการเชื่อมโยงคุณสมบัติโฮสต์ เชิงมุมตรวจสอบการผูกคุณสมบัติของโฮสต์โดยอัตโนมัติในระหว่างการตรวจจับการเปลี่ยนแปลง หากการเปลี่ยนแปลงมีผลผูกพันก็จะปรับปรุงองค์ประกอบโฮสต์ของคำสั่ง

@HostBinding- จะผูกคุณสมบัติกับองค์ประกอบโฮสต์หากการเปลี่ยนแปลงมีผลผูกพันHostBindingจะอัปเดตองค์ประกอบโฮสต์


หมายเหตุ:ลิงค์ทั้งสองถูกลบออกไปเมื่อเร็ว ๆ นี้ ส่วน " HostBinding-HostListening " ของคู่มือสไตล์อาจเป็นทางเลือกที่มีประโยชน์จนกว่าลิงก์จะกลับมา


ต่อไปนี้เป็นตัวอย่างโค้ดแบบง่ายเพื่อช่วยให้เข้าใจว่านี่หมายถึงอะไร:

DEMO: นี่คือตัวอย่างของการสาธิตแบบสดใน plunker - "ตัวอย่างง่ายๆเกี่ยวกับ @HostListener & @HostBinding"

  • ตัวอย่างนี้ผูกroleคุณสมบัติ - ประกาศด้วย@HostBinding- กับองค์ประกอบของโฮสต์
    • จำได้ว่าเป็นคุณลักษณะเนื่องจากเรากำลังใช้roleattr.role
    • <p myDir>กลายเป็น<p mydir="" role="admin">เมื่อคุณดูในเครื่องมือสำหรับนักพัฒนา
  • จากนั้นจะฟังonClickเหตุการณ์ที่ประกาศไว้@HostListenerซึ่งแนบกับองค์ประกอบโฮสต์ขององค์ประกอบเปลี่ยนไปroleด้วยการคลิกแต่ละครั้ง
    • การเปลี่ยนแปลงเมื่อ<p myDir>คลิกถูกคือแท็กเปิดของเปลี่ยนจาก<p mydir="" role="admin">เป็น<p mydir="" role="guest">และย้อนกลับ

directives.ts

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
มัณฑนากรนี้ยังคงใช้งานอยู่ดูเหมือนว่าลิงก์จะถูกลบออกจากเอกสารประกอบ angular2
CommonSenseCode

1
ใช่มันยังใช้งานอยู่ แต่ให้ฉันยืนยันอีกครั้ง ฉันจะอัพเดทคุณถ้าฉันสามารถหาสิ่งอื่นได้
micronyks

พวกเขาอยู่บนแผ่นโกง: angular.io/docs/ts/latest/guide/cheatsheet.html
Targaryen

1
@ Mr.EasyAnswersMcFly อัพเดตคำตอบพร้อมโน้ตและลิงก์ โปรดทราบว่ายังไม่มีเอกสารที่เหมาะสม
micronyks

1
@MuhammadSaleh สำหรับการเลื่อนมันยากที่จะบอกว่ามันนับและคำนวณอย่างไร ... แต่แน่นอนว่าแต่ละอินสแตนซ์จะมีผู้ฟังแยกต่างหาก
micronyks

112

เคล็ดลับสั้น ๆ ที่ช่วยให้ฉันจำได้ว่าพวกเขาทำอะไร -

HostBinding('value') myValue; เหมือนกันทุกประการ [value]="myValue"

และ

HostListener('click') myClick(){ } เหมือนกันทุกประการ (click)="myClick()"


HostBindingและHostListenerเขียนเป็นคำสั่งและอื่น ๆ(...)และ[..]เขียนไว้ในแม่แบบ (ของส่วนประกอบ)


9
อามันคลิก (ปุนตั้งใจ) กับฉันขอบคุณคำตอบนี้ @HostListenerเป็นวิธีที่จะไปเมื่อคุณไม่มีอะไรใน DOM สำหรับการเชื่อมเหตุการณ์ทั่วไปเช่นการป้อนข้อมูลด้วยแป้นพิมพ์ในกรณีของฉัน
MrBoJangles

47

นี่คือตัวอย่างการโฮเวอร์พื้นฐาน

คุณสมบัติแม่แบบของส่วนประกอบ:

แบบ

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

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

และคำสั่งของเรา

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
ฉันไม่เห็นคำตอบที่ยอมรับนี้เป็นคำตอบของคำถามที่ถาม คุณสนใจที่จะให้คำอธิบายบางอย่าง? เช่นเดียวกับสิ่งที่ c_colorrr, c_onEnterrr (), c_onLeaveeee ทำอะไรในข้อมูลโค้ดนี้โดยเฉพาะ?
luqo33

1
ฉันคิดว่ามันควรเปลี่ยนสีของเม้าส์ที่เข้ามาเป็นสีฟ้าและเม้าส์ทิ้งเป็นสีเหลือง
Michał Ziobro

คุณวางคำสั่งไว้ที่ไหนในมาร์กอัป ดูเหมือนว่าคุณจะวางไว้บนแท็ก body แต่นั่นจะอยู่นอกองค์ประกอบราก หากคุณสับสนกับคำตอบนี้ลิงก์นี้อาจช่วยng2.codecraft.tv/custom-directives/hostlistener-and-hostbinding
mtpultz

@mtpultz มันอยู่ในชั้นเรียน
serkan

33

อีกสิ่งที่ดีเกี่ยวกับการ@HostBindingที่คุณสามารถรวมกับ@Inputถ้าผูกพันของคุณอาศัยโดยตรงกับอินพุตเช่น:

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

1
คุณช่วยแบ่งปันตัวอย่างเกี่ยวกับการใช้งานด้วยได้@Input()ไหม
Mano

ตัวอย่างมีอยู่ในคำตอบของฉันคุณเพียงแค่เขียนทั้งสองนักตกแต่งหนึ่งหลังจากที่อื่น ๆ คำสั่งควรจะไม่เกี่ยวข้อง
altschuler

1
@HostBindingผมคิดว่าสิ่งที่ผมหายไปเป็นวิธีการที่แตกต่างกันนี้จากการใช้เพียง คุณต้องใช้เมื่อ@Inputใด
1252748

11

สิ่งหนึ่งที่เพิ่มความสับสนให้กับเรื่องนี้คือความคิดของนักตกแต่งที่ไม่ชัดเจนและเมื่อเราพิจารณาบางสิ่งเช่น ...

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

มันทำงานได้เพราะมันคือการเข้าถึงget คุณไม่สามารถใช้ฟังก์ชันที่เทียบเท่าได้:

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

มิฉะนั้นประโยชน์ของการใช้@HostBindingคือช่วยให้มั่นใจได้ว่าการตรวจจับการเปลี่ยนแปลงนั้นจะทำงานเมื่อค่าขอบเขตที่เปลี่ยนแปลง


9

สรุป:

  • @HostBinding: มัณฑนากรนี้ผูกคุณสมบัติคลาสเข้ากับคุณสมบัติขององค์ประกอบโฮสต์
  • @HostListener: มัณฑนากรนี้ผูกเมธอดคลาสกับเหตุการณ์ขององค์ประกอบโฮสต์

ตัวอย่าง:

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

}

ในตัวอย่างข้างต้นเกิดขึ้นดังต่อไปนี้:

  • ฟังเหตุการณ์จะถูกเพิ่มในเหตุการณ์คลิกซึ่งจะถูกไล่ออกเมื่อเหตุการณ์คลิกเกิดขึ้นที่ใดก็ได้ภายในองค์ประกอบ
  • colorคุณสมบัติในของเราAppComponentชั้นถูกผูกไว้กับstyle.colorทรัพย์สินในองค์ประกอบ ดังนั้นเมื่อใดก็ตามที่colorมีการอัปเดตstyle.colorสถานที่ให้บริการทรัพย์สินของเราจะเป็นเช่นนั้น
  • ผลที่ได้คือเมื่อใดก็ตามที่มีคนคลิกที่องค์ประกอบสีจะได้รับการปรับปรุง

การใช้งานใน@Directive:

แม้ว่าจะสามารถนำไปใช้กับส่วนประกอบนักตกแต่งเหล่านี้มักจะใช้ในคำสั่งแอตทริบิวต์ เมื่อใช้ในการ@Directiveเปลี่ยนแปลงโฮสต์องค์ประกอบที่วางคำสั่ง ตัวอย่างเช่นดูที่แม่แบบองค์ประกอบนี้:

<p p_Dir>some paragraph</p>

ที่นี่ p_Dir เป็นคำสั่งใน<p>องค์ประกอบ เมื่อ@HostBindingหรือถูกนำมาใช้ในระดับสั่งการเป็นเจ้าภาพในขณะนี้จะหมายถึง@HostListener<p>


6

ทฤษฎีที่มีศัพท์แสงน้อย

@Hostlistnening ข้อตกลงโดยทั่วไปกับองค์ประกอบโฮสต์พูด (ปุ่ม) ฟังการกระทำโดยผู้ใช้และดำเนินการฟังก์ชั่นบางอย่างพูดเตือน ("Ahoy!") ในขณะที่ @Hostbinding เป็นวิธีอื่น ที่นี่เราฟังการเปลี่ยนแปลงที่เกิดขึ้นกับปุ่มนั้นภายใน (พูดเมื่อมันถูกคลิกสิ่งที่เกิดขึ้นกับชั้นเรียน) และเราใช้การเปลี่ยนแปลงนั้นเพื่อทำอย่างอื่นพูดเปล่งสีใดสีหนึ่ง

ตัวอย่าง

นึกถึงสถานการณ์ที่คุณต้องการสร้างไอคอนรายการโปรดให้กับองค์ประกอบตอนนี้คุณรู้ว่าคุณต้องรู้ว่ารายการที่ชื่นชอบกับการเปลี่ยนแปลงระดับเราต้องการวิธีในการกำหนดสิ่งนี้ นั่นคือสิ่งที่ @Hostbinding เข้ามา

และในกรณีที่มีความจำเป็นที่จะต้องรู้ว่าการกระทำใดที่เกิดขึ้นจริงโดยผู้ใช้ที่เป็นที่ @Hostlistening เข้ามา


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