@@ -13,20 +13,23 @@ import {
1313Inject ,
1414Input ,
1515NgZone ,
16+ OnChanges ,
1617OnDestroy ,
1718OnInit ,
1819Optional ,
1920Output ,
20- Renderer2
21+ Renderer2 ,
22+ SimpleChanges
2123} from '@angular/core' ;
2224import { DOCUMENT } from '@angular/common' ;
2325import { BooleanInput , coerceBooleanProperty } from '@angular/cdk/coercion' ;
2426import { Subscription } from 'rxjs' ;
27+ import { filter } from 'rxjs/operators' ;
2528
2629import { createPopper , Instance , Options , Placement } from '@popperjs/core' ;
2730
28- import { DropdownService } from '../dropdown.service' ;
2931import { DropdownMenuDirective } from '../dropdown-menu/dropdown-menu.directive' ;
32+ import { DropdownService } from '../dropdown.service' ;
3033
3134// lightweight injection token
3235export abstract class DropdownToken { }
@@ -112,7 +115,7 @@ export class DropdownToggleDirective implements AfterViewInit {
112115exportAs :'cDropdown' ,
113116providers :[ DropdownService ]
114117} )
115- export class DropdownComponent implements AfterContentInit , OnDestroy , OnInit {
118+ export class DropdownComponent implements AfterContentInit , OnChanges , OnDestroy , OnInit {
116119
117120static ngAcceptInputType_dark :BooleanInput ;
118121static ngAcceptInputType_visible :BooleanInput ;
@@ -124,7 +127,9 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
124127private ngZone :NgZone ,
125128private changeDetectorRef :ChangeDetectorRef ,
126129public dropdownService :DropdownService
127- ) { }
130+ ) {
131+ this . dropdownStateSubscribe ( ) ;
132+ }
128133
129134/**
130135 * Set alignment of dropdown menu.
@@ -237,10 +242,12 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
237242 @Input ( )
238243set visible ( value :boolean ) {
239244const _value = coerceBooleanProperty ( value ) ;
240- this . activeTrap = _value ;
241- this . _visible = _value ;
242- _value ?this . createPopperInstance ( ) :this . destroyPopperInstance ( ) ;
243- this . visibleChange . emit ( _value ) ;
245+ if ( _value !== this . _visible ) {
246+ this . activeTrap = _value ;
247+ this . _visible = _value ;
248+ _value ?this . createPopperInstance ( ) :this . destroyPopperInstance ( ) ;
249+ this . visibleChange . emit ( _value ) ;
250+ }
244251}
245252
246253get visible ( ) :boolean {
@@ -291,13 +298,15 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
291298dropdownStateSubscribe ( subscribe :boolean = true ) :void {
292299if ( subscribe ) {
293300this . dropdownStateSubscription =
294- this . dropdownService . dropdownState$ . subscribe ( ( state ) => {
295- if ( this === state . dropdown ) {
296- if ( 'visible' in state ) {
297- state ?. visible === 'toggle'
298- ?this . toggleDropdown ( )
299- :( this . visible = state . visible ) ;
300- }
301+ this . dropdownService . dropdownState$ . pipe (
302+ filter ( ( state ) => {
303+ return this === state . dropdown ;
304+ } )
305+ ) . subscribe ( ( state ) => {
306+ if ( 'visible' in state ) {
307+ state ?. visible === 'toggle'
308+ ?this . toggleDropdown ( )
309+ :( this . visible = state . visible ) ;
301310}
302311} ) ;
303312} else {
@@ -322,10 +331,15 @@ export class DropdownComponent implements AfterContentInit, OnDestroy, OnInit {
322331}
323332
324333ngOnInit ( ) :void {
325- this . dropdownStateSubscribe ( ) ;
326334this . setVisibleState ( this . visible ) ;
327335}
328336
337+ ngOnChanges ( changes :SimpleChanges ) :void {
338+ if ( changes [ 'visible' ] && ! changes [ 'visible' ] . firstChange ) {
339+ this . setVisibleState ( changes [ 'visible' ] . currentValue ) ;
340+ }
341+ }
342+
329343ngOnDestroy ( ) :void {
330344this . clearListeners ( ) ;
331345this . dropdownStateSubscribe ( false ) ;