рдПрдВрдЧреБрд▓рд░ рдореЗрдВ рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди

рдкрд░рд┐рдЪрдп


рдХреЛрдгреАрдп рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ (eventName)="onEventName($event)" рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рдШрдЯрдирд╛рдУрдВ рдХреА рд╕рджрд╕реНрдпрддрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдШреЛрд╖рдгрд╛рддреНрдордХ рддрд░реАрдХрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред ChangeDetectionStrategy.OnPush рдкрд░рд┐рд╡рд░реНрддрди рдЬрд╛рдБрдЪ рдиреАрддрд┐ рдХреЗ рд╕рд╛рде, рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдХреЗрд╡рд▓ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрдирдкреБрдЯ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рд╡рд░реНрддрди рдЬрд╛рдБрдЪ рдЪрдХреНрд░ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╣рдореЗрдВ ChangeDetectionStrategy.OnPush рд╣реИред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдпрджрд┐ рд╣рдо <input> рддрддреНрд╡ рдкрд░ (input) рдИрд╡реЗрдВрдЯ рд╕реБрдирддреЗ рд╣реИрдВ, рддреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдЗрдирдкреБрдЯ рдлрд╝реАрд▓реНрдб рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдиреЗ рдкрд░ рдкрд░рд┐рд╡рд░реНрддрди рдХреА рдЬрд╛рдВрдЪ рд╢реБрд░реВ рдирд╣реАрдВ рд╣реЛрдЧреАред рдЗрд╕рдореЗрдВ рдмрд╣реБрдд рд╕реБрдзрд╛рд░ рд╣реЛрддрд╛ рд╣реИ
рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдиреАрддрд┐ ( ChangeDetectionStrategy.Default ) рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рдиред рдирд┐рд░реНрджреЗрд╢реЛрдВ рдореЗрдВ, рд╣рдо @HostListener('eventName') рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣реЛрд╕реНрдЯ рддрддреНрд╡ рдХреА рдШрдЯрдирд╛рдУрдВ рдХреА рднреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВред


рдореЗрд░реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ, рдЕрдХреНрд╕рд░ рдРрд╕реЗ рдорд╛рдорд▓реЗ рд╣реЛрддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдШрдЯрдирд╛ рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдпрджрд┐ рдХреЛрдИ рд╢рд░реНрдд рдкреВрд░реА рд╣реЛрддреА рд╣реИред рдпрд╛рдиреА рд╣реИрдВрдбрд▓рд░ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:


 class ComponentWithEventHandler { // ... onEvent(event: Event) { if (!this.condition) { return; } // Handling event ... } } 

рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЕрдЧрд░ рд╢рд░реНрдд рдкреВрд░реА рдирд╣реАрдВ рд╣реБрдИ рд╣реИ рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЛрдИ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдирд╣реАрдВ рд╣реБрдИ рд╣реИ, рддрдм рднреА рдкрд░рд┐рд╡рд░реНрддрди рд╕рддреНрдпрд╛рдкрди рдЪрдХреНрд░ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд▓рдЧрд╛рддрд╛рд░ рдШрдЯрдирд╛рдУрдВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЬреИрд╕реЗ рдХрд┐ scroll рдпрд╛ mousemove , рдпрд╣ рдЖрд╡реЗрджрди рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдкрд░ рдкреНрд░рддрд┐рдХреВрд▓ рдкреНрд░рднрд╛рд╡ рдбрд╛рд▓ рд╕рдХрддрд╛ рд╣реИред


рдШрдЯрдХ рдпреВрдЖрдИ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдЬреЛ рдореИрдВ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдбреНрд░реЙрдк-рдбрд╛рдЙрди рдореЗрдиреВ рдХреЗ рдЕрдВрджрд░ mousemove рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрдиреЗ рд╕реЗ рд╣рд░ рдорд╛рдЙрд╕ рдЖрдВрджреЛрд▓рди рдХреЗ рд▓рд┐рдП рдкреВрд░реЗ рдШрдЯрдХ рдкреЗрдбрд╝ рдореЗрдВ рдмрджрд▓рд╛рд╡реЛрдВ рдХреА рдПрдХ рдХрдореА рд╢реБрд░реВ рд╣реЛ рдЧрдИред рд╕рд╣реА рдореЗрдиреВ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рдЙрд╕ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛, рд▓реЗрдХрд┐рди рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЕрдиреБрдХреВрд▓рди рдХреЗ рд▓рд╛рдпрдХ рдерд╛ред рдЗрд╕ рдкрд░ рдЕрдзрд┐рдХ рдиреАрдЪреЗред


рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдпреВрдЖрдИ рддрддреНрд╡реЛрдВ рдХреЗ рд▓рд┐рдП рдРрд╕реЗ рдХреНрд╖рдг рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИрдВред рдкреГрд╖реНрда рдкрд░ рдЙрдирдореЗрдВ рд╕реЗ рдХрдИ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рджрд░реНрд╢рди рдкрд░ рдорд╛рдВрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдЖрдк ngZone рдХреЛ рджрд░рдХрд┐рдирд╛рд░ ngZone рдШрдЯрдирд╛рдУрдВ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрдХрд░ рд╕реНрдерд┐рддрд┐ рдХреЛ рдареАрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, Observable.fromEvent рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдФрд░ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд▓рд┐рдП рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдХреЗ рдЬрд╛рдБрдЪ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ changeDetectorRef.markForCheck() ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╛рд░реНрдп рдХрд╛ рдПрдХ рдЯрди рдЬреЛрдбрд╝рддрд╛ рд╣реИ рдФрд░ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдХреЛрдгреАрдп рдЙрдкрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рдмрдирд╛рддрд╛ рд╣реИред


рдпрд╣ рдХреЛрдИ рд░рд╣рд╕реНрдп рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреЛрдгреАрдп рдЖрдкрдХреЛ рддрдерд╛рдХрдерд┐рдд рдЫрджреНрдо рдШрдЯрдирд╛рдУрдВ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдпрд╣ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдХрд┐рди рдШрдЯрдирд╛рдУрдВ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВред рд╣рдо (keydown.enter)="onEnter($event)" рдФрд░ рд╣реИрдВрдбрд▓рд░ (рдФрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рдкрд░рд┐рд╡рд░реНрддрди рдЪрдХреНрд░) рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдХреЗрд╡рд▓ рддрднреА Enter рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЬрдм Enter рдХреБрдВрдЬреА рджрдмрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд╢реЗрд╖ рдкреНрд░реЗрд╕ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдЖрдк рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдгреАрдп рдХреЗ рд╕рдорд╛рди рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ рдПрдХ рдмреЛрдирд╕ рдХреЗ рд░реВрдк рдореЗрдВ, .prevent рдФрд░ .stop рдЬреЛрдбрд╝реЗрдВ, рдЬреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рд░рджреНрдж рдХрд░ рджреЗрдЧрд╛ рдФрд░ рдШрдЯрдирд╛ рдХреЛ рдЕрдкрдиреЗ рдЖрдк .stop рд╕реЗ рд░реЛрдХ рджреЗрдЧрд╛ред


EventManagerPlugin



рдХреЛрдгреАрдп рдШрдЯрдирд╛рдУрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП EventManager рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдореЗрдВ рддрдерд╛рдХрдерд┐рдд рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реИ рдЬреЛ рдЕрдореВрд░реНрдд EventManagerPlugin рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рдШрдЯрдирд╛ (рдирд╛рдо рд╕реЗ) рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд▓рдЧрдЗрди рдХреЗ рд▓рд┐рдП рдЗрд╡реЗрдВрдЯ рд╕рджрд╕реНрдпрддрд╛ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ EventManagerPlugin ред Angular рдХреЗ рдЕрдВрджрд░ рдХрдИ рдкреНрд▓рдЧрдЗрдиреНрд╕ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ HammerJS рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдФрд░ keydown.enter рдЬреИрд╕реА рд╕рдордЧреНрд░ рдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рдПрдХ рдкреНрд▓рдЧрдЗрди keydown.enter ред рдпрд╣ рдХреЛрдгреАрдп рдХрд╛ рдЖрдВрддрд░рд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ, рдФрд░ рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдЕрдзреАрди рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдХреЗ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдкрд░ рдореБрджреНрджреЗ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ 3 рд╕рд╛рд▓ рдмреАрдд рдЪреБрдХреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕ рджрд┐рд╢рд╛ рдореЗрдВ рдХреЛрдИ рдкреНрд░рдЧрддрд┐ рдирд╣реАрдВ рд╣реБрдИ рд╣реИ:


https://github.com/angular/angular/issues/3929


рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЗрд╕рдореЗрдВ рдХреНрдпрд╛ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ? рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдпреЗ рд╡рд░реНрдЧ рдЖрдВрддрд░рд┐рдХ рд╣реИрдВ рдФрд░ рдЗрдирд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдирд╣реАрдВ рд▓рд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХреЗ рд▓рд┐рдП рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рдЯреЛрдХрди рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рдо рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреНрд▓рдЧрдЗрдиреНрд╕ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдирдХреЗ рд╕рд╛рде рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рддрдВрддреНрд░ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдпрджрд┐ рдЖрдк EventManagerPlugin рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЛ EventManagerPlugin , рддреЛ рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рд╣рдо рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдирд╣реАрдВ рдХрд░ рдкрд╛рдПрдВрдЧреЗ, рдЕрдзрд┐рдХрд╛рдВрд╢ рднрд╛рдЧ рдХреЗ рд▓рд┐рдП рдпрд╣ рд╕рд╛рд░ рд╣реИ рдФрд░ рдЕрдкрдиреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд╡рд░реНрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ:


https://github.com/angular/angular/blob/master/packages/platform-browser/src/dom/events/event_manager.ts#L92


рдореЛрдЯреЗ рддреМрд░ рдкрд░, рдкреНрд▓рдЧрдЗрди рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХреНрдпрд╛ рд╡рд╣ рдЗрд╕ рдШрдЯрдирд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ рдФрд░ рдПрдХ рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдФрд░ рд╡реИрд╢реНрд╡рд┐рдХ рд╣реИрдВрдбрд▓рд░ ( body , window рдФрд░ document ) рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рд╣рдо рд╕рдВрд╢реЛрдзрдХ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ .filter , .prevent рдФрд░ .stop рдЙрдиреНрд╣реЗрдВ рд╣рдорд╛рд░реЗ рдкреНрд▓рдЧрдЗрди рд╕реЗ рдмрд╛рдВрдзрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЖрд╡рд╢реНрдпрдХ рд╡рд┐рдзрд┐ supports :


 const FILTER = '.filter'; const PREVENT = '.prevent'; const STOP = '.stop'; class FilteredEventPlugin { supports(event: string): boolean { return ( event.includes(FILTER) || event.includes(PREVENT) || event.includes(STOP) ); } } 

рддреЛ EventManager рд╕рдордЭ рдЬрд╛рдПрдЧрд╛ рдХрд┐ рдШрдЯрдирд╛рдУрдВ рдХреЗ рдирд╛рдо рдкрд░ рдХреБрдЫ EventManager рд╣реИрдВ рдЬреЛ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдкреНрд▓рдЧрдЗрди рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдлрд┐рд░ рд╣рдореЗрдВ рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рдо рд╡реИрд╢реНрд╡рд┐рдХ рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рдореЗрдВ рд░реБрдЪрд┐ рдирд╣реАрдВ рд░рдЦрддреЗ рд╣реИрдВ, рдЙрдирдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдРрд╕реЗ рдЙрдкрдХрд░рдгреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдмрд╣реБрдд рдХрдо рдЖрдо рд╣реИ, рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реЛрдЧрд╛ред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдЕрдкрдиреЗ рдореЙрдбрд┐рдлрд╛рдпрд░реНрд╕ рдХреЛ рдЗрд╡реЗрдВрдЯ рдХреЗ рдирд╛рдо рд╕реЗ рд╣рдЯрд╛рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ EventManager рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ EventManager рддрд╛рдХрд┐ рдпрд╣ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рдмрд┐рд▓реНрдЯ-рдЗрди рдкреНрд▓рдЧ-рдЗрди EventManager :


 class FilteredEventPlugin { supports(event: string): boolean { // ... } addGlobalEventListener( element: string, eventName: string, handler: Function, ): Function { const event = eventName .replace(FILTER, '') .replace(PREVENT, '') .replace(STOP, ''); return this.manager.addGlobalEventListener(element, event, handler); } } 

рдПрдХ рдирд┐рдпрдорд┐рдд рддрддреНрд╡ рдкрд░ рдПрдХ рдШрдЯрдирд╛ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдореЗрдВ рдЕрдкрдирд╛ рддрд░реНрдХ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╣реИрдВрдбрд▓рд░ рдХреЛ рд▓реВрдк рдореЗрдВ рд▓рдкреЗрдЯрддреЗ рд╣реИрдВ рдФрд░ рдЕрдкрдиреЗ EventManager рдмрд┐рдирд╛ рдЗрд╡реЗрдВрдЯ рдХреЛ EventManager рд╡рд╛рдкрд╕ EventManager , рдЗрд╕реЗ ngZone рдмрд╛рд╣рд░ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ, рдкрд░рд┐рд╡рд░реНрддрди рдЬрд╛рдБрдЪ рдЪрдХреНрд░ рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП:


 class FilteredEventPlugin { supports(event: string): boolean { // ... } addEventListener( element: HTMLElement, eventName: string, handler: Function, ): Function { const event = eventName .replace(FILTER, '') .replace(PREVENT, '') .replace(STOP, ''); //     const filtered = (event: Event) => { // ... }; const wrapper = () => this.manager.addEventListener(element, event, filtered); return this.manager.getZone().runOutsideAngular(wrapper); } /* addGlobalEventListener(...): Function { ... } */ } 

рдЗрд╕ рд╕реНрддрд░ рдкрд░, рд╣рдорд╛рд░реЗ рдкрд╛рд╕: рдШрдЯрдирд╛ рдХрд╛ рдирд╛рдо, рдШрдЯрдирд╛ рд╕реНрд╡рдпрдВ, рдФрд░ рд╡рд╣ рддрддреНрд╡ рдЬрд┐рд╕ рдкрд░ рдЗрд╕реЗ рд╕реБрдирд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред рдпрд╣рд╛рдВ рдкрд╣реБрдВрдЪрдиреЗ рд╡рд╛рд▓рд╛ рд╣реИрдВрдбрд▓рд░ рдЗрд╕ рдШрдЯрдирд╛ рдХреЗ рд▓рд┐рдП рд╕реМрдВрдкрд╛ рдЧрдпрд╛ рд╣реИрдВрдбрд▓рд░ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдВрдЧреБрд▓рд░ рджреНрд╡рд╛рд░рд╛ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреНрд░рдпреЛрдЬрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдмрдирд╛рдИ рдЧрдИ рдХреНрд▓реЛрдЬрд░ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХрд╛ рдЕрдВрдд рд╣реИред


рдПрдХ рд╕рдорд╛рдзрд╛рди рддрддреНрд╡ рдореЗрдВ рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛, рдЬреЛ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдпрд╛ рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рдХрднреА-рдХрднреА, рдПрдХ рдирд┐рд░реНрдгрдп рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдП, рд╕реНрд╡рдпрдВ рдШрдЯрдирд╛ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ: рдХреНрдпрд╛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЛ рд░рджреНрдж рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдХреМрди рд╕рд╛ рддрддреНрд╡ рдШрдЯрдирд╛ рдХрд╛ рд╕реНрд░реЛрдд рд╣реИ, рдЖрджрд┐ред рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд┐рд╢реЗрд╖рддрд╛ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ, рд╣рдореЗрдВ рдПрдХ рдлрд┐рд▓реНрдЯрд░ рдлрд╝рдВрдХреНрд╢рди рд╕реЗрдЯ рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдЦреЛрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдШрдЯрдирд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдФрд░ true рдпрд╛ false рд░рд┐рдЯрд░реНрди рджреЗрддрд╛ true ред рдлрд┐рд░ рд╣рдо рдЕрдкрдиреЗ рд╣реИрдВрдбрд▓рд░ рдХрд╛ рд╡рд░реНрдгрди рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 const filtered = (event: Event) => { const filter = getOurHandler(some_arguments); if ( !eventName.includes(FILTER) || !filter || filter(event) ) { if (eventName.includes(PREVENT)) { event.preventDefault(); } if (eventName.includes(STOP)) { event.stopPropagation(); } this.manager.getZone().run(() => handler(event)); } }; 

рдирд┐рд░реНрдгрдп


рд╕рдорд╛рдзрд╛рди рдПрдХ рд╕рд┐рдВрдЧрд▓рдЯрди рд╕реЗрд╡рд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ рдЬреЛ рдЗрди рдкрддреНрд░рд╛рдЪрд╛рд░ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддрддреНрд╡реЛрдВ рдХреЗ рдкрддреНрд░рд╛рдЪрд╛рд░ рдХреЛ рдШрдЯрдирд╛ / рдлрд╝рд┐рд▓реНрдЯрд░ рдЬреЛрдбрд╝реЗ рдФрд░ рд╕рд╣рд╛рдпрдХ рд╕рдВрд╕реНрдерд╛рдУрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреА рд╣реИред рдмреЗрд╢рдХ, рдПрдХ рддрддреНрд╡ рдкрд░ рдПрдХ рд╣реА рдШрдЯрдирд╛ рдХреЗ рд▓рд┐рдП рдХрдИ рд╣реИрдВрдбрд▓рд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди, рдПрдХ рдирд┐рдпрдо рдХреЗ рд░реВрдк рдореЗрдВ, рдпрд╣ @HostListener рдФрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ рдПрдХ рдШрдЯрдХ рдЙрдЪреНрдЪ рд╕реНрддрд░ рдкрд░ рд╕реНрдерд╛рдкрд┐рдд рд╣реИрдВрдбрд▓рд░ рджреЛрдиреЛрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╣рдо рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХрд╛ рдкреВрд░реНрд╡рд╛рднрд╛рд╕ рдХрд░реЗрдВрдЧреЗ, рдЬрдмрдХрд┐ рдЕрдиреНрдп рдорд╛рдорд▓реЗ рдЗрд╕рдХреА рд╡рд┐рд╢рд┐рд╖реНрдЯрддрд╛ рдХреЗ рдХрд╛рд░рдг рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдмрд╣реБрдд рдХрдо рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВред


рдореБрдЦреНрдп рд╕реЗрд╡рд╛ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдорд╛рдирдЪрд┐рддреНрд░ рдФрд░ рд╕реЗрдЯрд┐рдВрдЧ, рдкреНрд░рд╛рдкреНрддрд┐ рдФрд░ рд╕рдлрд╛рдИ рдлрд┐рд▓реНрдЯрд░ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рддрд░реАрдХреЗ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:


 export type Filter = (event: Event) => boolean; export type Filters = {[key: string]: Filter}; class FilteredEventMainService { private elements: Map<Element, Filters> = new Map(); register(element: Element, filters: Filters) { this.elements.set(element, filters); } unregister(element: Element) { this.elements.delete(element); } getFilter(element: Element, event: string): Filter | null { const map = this.elements.get(element); return map ? map[event] || null : null; } } 

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдЗрд╕ рд╕реЗрд╡рд╛ рдХреЛ рдкреНрд▓рдЧрдЗрди рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рддрддреНрд╡ рдФрд░ рдШрдЯрдирд╛ рдХреЗ рдирд╛рдо рд╕реЗ рдПрдХ рдлрд╝рд┐рд▓реНрдЯрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред @HostListener рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП @HostListener рд╣рдо рдПрдХ рдФрд░ рдЫреЛрдЯреА рд╕реЗрд╡рд╛ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдЬреЛ рдШрдЯрдХ рдХреЗ рд╕рд╛рде рд░рд╣реЗрдЧреА рдФрд░ рдЗрд╕реЗ рд╣рдЯрд╛рдП рдЬрд╛рдиреЗ рдкрд░ рдЙрдкрдпреБрдХреНрдд рдлрд╝рд┐рд▓реНрдЯрд░ рд╕рд╛рдлрд╝ рдХрд░реЗрдВ:


 export class EventFiltersService { constructor( @Inject(ElementRef) private readonly elementRef: ElementRef, @Inject(FilteredEventMainService) private readonly mainService: FilteredEventMainService, ) {} ngOnDestroy() { this.mainService.unregister(this.elementRef.nativeElement); } register(filters: Filters) { this.mainService.register(this.elementRef.nativeElement, filters); } } 

рддрддреНрд╡реЛрдВ рдореЗрдВ рдлрд╝рд┐рд▓реНрдЯрд░ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдПрдХ рд╕рдорд╛рди рдирд┐рд░реНрджреЗрд╢ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ:


 class EventFiltersDirective { @Input() set eventFilters(filters: Filters) { this.mainService.register(this.elementRef.nativeElement, filters); } constructor( @Inject(ElementRef) private readonly elementRef: ElementRef, @Inject(FilteredEventMainService) private readonly mainService: FilteredEventMainService, ) {} ngOnDestroy() { this.mainService.unregister(this.elementRef.nativeElement); } } 

рдпрджрд┐ рдШрдЯрдХ рдХреЗ рдЕрдВрджрд░ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реЗрд╡рд╛ рд╣реИ, рддреЛ рд╣рдо рдирд┐рд░реНрджреЗрд╢ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЛ рдЙрд╕ рдкрд░ рд▓рдЯрдХрд╛рдП рдЬрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрдВрдЧреЗред рдЕрдВрдд рдореЗрдВ, рдпрд╣ рд▓рдЧрднрдЧ рд╣рдореЗрд╢рд╛ рдШрдЯрдХ рдХреЛ рдХреЗрд╡рд▓ рдЙрд╕ рддрддреНрд╡ рдХреЗ рд╕рд╛рде рд▓рдкреЗрдЯрдХрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╣рдорд╛рд░рд╛ рдирд┐рд░реНрджреЗрд╢ рд╕реМрдВрдкрд╛ рдЬрд╛рдПрдЧрд╛ред рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреЛрдИ рд╕реЗрд╡рд╛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рддрддреНрд╡ рдкрд░ рдореМрдЬреВрдж рд╣реИ, рд╣рдо рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ рдЗрд╕реЗ рдирд┐рд░реНрджреЗрд╢ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░реЗрдВрдЧреЗ:


 class EventFiltersDirective { // ... constructor( @Optional() @Self() @Inject(FiltersService) private readonly filtersService: FiltersService | null, ) {} // ... } 

рдпрджрд┐ рдпрд╣ рд╕реЗрд╡рд╛ рдореМрдЬреВрдж рд╣реИ, рддреЛ рд╣рдо рдпрд╣ рдХрд╣рддреЗ рд╣реБрдП рдПрдХ рд╕рдВрджреЗрд╢ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВрдЧреЗ рдХрд┐ рдпрд╣ рдирд┐рд░реНрджреЗрд╢ рдЗрд╕рдХреЗ рд▓рд┐рдП рд▓рд╛рдЧреВ рдирд╣реАрдВ рд╣реИ:


 class EventFiltersDirective { @Input() set eventFilters(filters: Filters) { if (this.eventFiltersService === null) { console.warn(ALREADY_APPLIED_MESSAGE); return; } this.mainService.register(this.elementRef.nativeElement, filters); } // ... } 


рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧ


рд╕рднреА рд╡рд░реНрдгрд┐рдд рдХреЛрдб рд╕реНрдЯреИрдХрдмреНрд▓рд┐рдЯреНрдЬрд╝ рдкрд░ рдкрд╛рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ:


https://stackblitz.com/edit/angular-event-filter


рдЙрдкрдпреЛрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рдПрдХ рдХрд╛рд▓реНрдкрдирд┐рдХ select рд╡рд╣рд╛рдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ - рдПрдХ рдореЛрдбрд▓ рд╡рд┐рдВрдбреЛ рдХреЗ рдЕрдВрджрд░ рдПрдХ рдШрдЯрдХ - рдФрд░ рдЗрд╕рдХреЗ рдбреНрд░реЙрдкрдбрд╛рдЙрди рдХреА рднреВрдорд┐рдХрд╛ рдореЗрдВ рдПрдХ рд╕рдВрджрд░реНрдн рдореЗрдиреВред рд╕рдВрджрд░реНрдн рдореЗрдиреВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрджрд┐ рдЖрдк рдХрд┐рд╕реА рднреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рд╡реНрдпрд╡рд╣рд╛рд░ рд╣рдореЗрд╢рд╛ рдирд┐рдореНрди рд╣реЛрддрд╛ рд╣реИ: рдЬрдм рдЖрдк рдХрд┐рд╕реА рдЖрдЗрдЯрдо рдкрд░ рд╣реЛрд╡рд░ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдлрд╝реЛрдХрд╕ рдХрд░рддрд╛ рд╣реИ, рдЬрдм рдЖрдк рдХреАрдмреЛрд░реНрдб рдкрд░ рддреАрд░ рджрдмрд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдЗрдЯрдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдлрд╝реЛрдХрд╕ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рдорд╛рдЙрд╕ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдлрд╝реЛрдХрд╕ рддрддреНрд╡ рдкрд░ рд▓реМрдЯрддрд╛ рд╣реИ рдорд╛рдЙрд╕ рдкреЙрдЗрдВрдЯрд░ рдХреЗ рдиреАрдЪреЗ рд╕реНрдерд┐рдд рд╣реИред рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, mousemove рдШрдЯрдирд╛ рдХреЗ рд▓рд┐рдП рдЕрдирд╛рд╡рд╢реНрдпрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдПрдВ рджрд░реНрдЬрдиреЛрдВ рдмреЗрдХрд╛рд░ рдкрд░рд┐рд╡рд░реНрддрди рдЪрдХреНрд░реЛрдВ рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд░ рд╕рдХрддреА рд╣реИрдВред рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдШрдЯрдирд╛ рдХреЗ target рддрддреНрд╡ рдХреЗ рдлрд╝реЛрдХрд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪреЗрдХ рд╕реЗрдЯ рдХрд░рдХреЗ, рд╣рдо рдЗрди рдЕрдирд╛рд╡рд╢реНрдпрдХ рдЯреНрд░рд┐рдЧрд░рд┐рдВрдЧ рдХреЛ рдХрд╛рдЯ рд╕рдХрддреЗ рд╣реИрдВ, рдХреЗрд╡рд▓ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдлреЛрдХрд╕ рдХреЛ рд▓реЗ рдЬрд╛рддреЗ рд╣реИрдВред



рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕ select рдШрдЯрдХ рдореЗрдВ @HostListener рд╕рдмреНрд╕рдХреНрд░рд┐рдкреНрд╢рди рдкрд░ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рд╣реИред рдЬрдм рдЖрдк рдкреЙрдкрдЕрдк рдХреЗ рдЕрдВрджрд░ Esc рджрдмрд╛рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдмрдВрдж рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдХреЗрд╡рд▓ рддрднреА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрдм рдпрд╣ рдХреНрд▓рд┐рдХ рдХреБрдЫ рдиреЗрд╕реНрдЯреЗрдб рдШрдЯрдХ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рдерд╛ рдФрд░ рдЗрд╕рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред select Esc рджрдмрд╛рдиреЗ рдкрд░ рдбреНрд░реЙрдкрдбрд╛рдЙрди рдмрдВрдж рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдлрд╝реЛрдХрд╕ рдХреЛ рдлрд╝реАрд▓реНрдб рдореЗрдВ рд╡рд╛рдкрд╕ рдХрд░ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрдВрдж рд╣реИ, рддреЛ рдпрд╣ рдИрд╡реЗрдВрдЯ рдХреЛ рдкреЙрдк рдЕрдк рдХрд░рдиреЗ рд╕реЗ рдирд╣реАрдВ рд░реЛрдХрддрд╛ рд╣реИ рдФрд░ рдореЛрдбрд▓ рд╡рд┐рдВрдбреЛ рдХреЛ рдмрд╛рдж рдореЗрдВ рдмрдВрдж рдХрд░ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдПрдХ рд╕рдЬреНрдЬрд╛рдХрд╛рд░ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:


@HostListener('keydown.esc.filtered.stop') , рдЬрдм @HostListener('keydown.esc.filtered.stop') : () => this.opened ред


рдЪреВрдВрдХрд┐ select рдХрдИ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рддрддреНрд╡реЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдШрдЯрдХ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдлреЛрдХрд╕ рдкреЙрдкрдЕрдк рдШрдЯрдирд╛рдУрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрд╕рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рдлреЛрдХрд╕ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИред рд╡реЗ рдлрд╝реЛрдХрд╕ рдореЗрдВ рд╕рднреА рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд╕рд╛рде рдШрдЯрд┐рдд рд╣реЛрдВрдЧреЗ, рдЬрд┐рд╕рдореЗрдВ рд╡реЗ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИрдВ рдЬреЛ рдШрдЯрдХ рдХреА рд╕реАрдорд╛рдУрдВ рдХреЛ рдирд╣реАрдВ рдЫреЛрдбрд╝рддреЗ рд╣реИрдВред рдЗрд╕ рдИрд╡реЗрдВрдЯ рдореЗрдВ рдПрдХ relatedTarget рдлрд╝реАрд▓реНрдб рд╣реИ рдЬреЛ relatedTarget рдХрд┐ рдлрд╝реЛрдХрд╕ рдХрд╣рд╛рдВ рдЪрд▓рддрд╛ рд╣реИ рдЗрд╕рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рд╕рдордЭ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рд╣рдорд╛рд░реЗ рдШрдЯрдХ рдХреЗ рд▓рд┐рдП blur рдШрдЯрдирд╛ рдХрд╛ рдПрдирд╛рд▓реЙрдЧ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реИ:


 class SelectComponent { // ... @HostListener('focusout.filtered') onBlur() { this.opened = false; } // ... } 

рдлрд┐рд▓реНрдЯрд░, рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ, рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:


 const focusOutFilter = ({relatedTarget}: FocusEvent) => !this.elementRef.nativeElement.contains(relatedTarget); 

рдирд┐рд╖реНрдХрд░реНрд╖


рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдХреЛрдгреАрдп рдореЗрдВ рдпреМрдЧрд┐рдХ рдХреАрд╕реНрдЯреНрд░реЛрдХреНрд╕ рдХрд╛ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдЕрднреА рднреА NgZone рдореЗрдВ рд╢реБрд░реВ рд╣реЛрдЧрд╛, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдпрд╣ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХрд░реЗрдЧрд╛ред рдпрджрд┐ рд╣рдо рдЪрд╛рд╣рддреЗ рдереЗ, рддреЛ рд╣рдо рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рд╕рд╣рд╛рд░рд╛ рдирд╣реАрдВ рд▓реЗ рд╕рдХрддреЗ рдереЗ, рд▓реЗрдХрд┐рди рдкреНрд░рджрд░реНрд╢рди рд▓рд╛рдн рдЫреЛрдЯрд╛ рд╣реЛрдЧрд╛, рдФрд░ рдЙрдиреНрдирдпрди рдХреЗ рджреМрд░рд╛рди рдХреЛрдгреАрдп рдХреА рдЖрдВрддрд░рд┐рдХ "рд░рд╕реЛрдИ" рдореЗрдВ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдХреНрд╖рддрд┐ рд╣реЛ рд╕рдХрддреА рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рдпрд╛ рддреЛ рд╕рдордЧреНрд░ рдШрдЯрдирд╛ рдХрд╛ рдкрд░рд┐рддреНрдпрд╛рдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдпрд╛ рд╕реАрдорд╛ рдСрдкрд░реЗрдЯрд░ рдХреЗ рд╕рдорд╛рди рдПрдХ рдлрд┐рд▓реНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдмрд╕ рд╣реИрдВрдбрд▓рд░ рдХреЛ рдХреЙрд▓ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрд╣рд╛рдВ рдпрд╣ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдирд╣реАрдВ рд╣реИред


рдХреЛрдгреАрдп рдХреЗ рдЖрдВрддрд░рд┐рдХ рдШрдЯрдирд╛ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЦреАрдВрдЪрдирд╛ рдПрдХ рд╕рд╛рд╣рд╕рд┐рдХ рдЙрдкрдХреНрд░рдо рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЖрдВрддрд░рд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рд╣рдореЗрдВ рд▓реЗрдЦ рдХреЗ рджреВрд╕рд░реЗ рдЦрдВрдб рдореЗрдВ рджрд┐рдП рдЧрдП рдЕрдкрдбреЗрдЯ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, GitHub рдкрд░ рдХрд╛рд░реНрдп рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдм рд╣рдо рдЖрд╕рд╛рдиреА рд╕реЗ рд╣реИрдВрдбрд▓рд░ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ; рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рджрд╕реНрдпрддрд╛ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рддреЗ рд╕рдордп рдЗрд╡реЗрдВрдЯ рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХреЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рддрд░реАрдХреЗ рд╕реЗ stopPropagation рд▓рд┐рдП рдЖрд╕рд╛рдиреА рд╕реЗ stopPropagation рдФрд░ stopPropagation рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рд╣реИред рднрд╡рд┐рд╖реНрдп рд╕реЗ, рд╕рдЬрд╛рд╡рдЯрдХрд░реНрддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрдирдХреЗ рдареАрдХ рдмрдЧрд▓ рдореЗрдВ @HostListener рд▓рд┐рдП рдлрд╝рд┐рд▓реНрдЯрд░ рдШреЛрд╖рд┐рдд рдХрд░рдирд╛ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрдЧрд╛ред рдЕрдЧрд▓реЗ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВрдиреЗ рдХрдИ рд╕рдЬреНрдЬрд╛рдХрд╛рд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рдИ рд╣реИ рдЬреЛ рд╣рдордиреЗ рдШрд░ рдкрд░ рдмрдирд╛рдП рд╣реИрдВ, рдФрд░ рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред

Source: https://habr.com/ru/post/hi429692/


All Articles