@@ -26,7 +26,7 @@ import {
2626} from '@angular/core' ;
2727import { ControlValueAccessor , NG_VALUE_ACCESSOR } from '@angular/forms' ;
2828import { merge , Observable , Subject } from 'rxjs' ;
29- import { takeWhile } from 'rxjs/operators' ;
29+ import { startWith , switchMap , takeWhile } from 'rxjs/operators' ;
3030
3131import {
3232 NbAdjustableConnectedPositionStrategy ,
@@ -252,10 +252,13 @@ export class NbSelectComponent<T> implements OnInit, AfterViewInit, AfterContent
252252 */
253253 overlayPosition : NbPosition = '' as NbPosition ;
254254
255- /**
256- * Stream of events that will fire when one of the options fire selectionChange event.
257- * */
258255 protected selectionChange$ : Subject < NbOptionComponent < T > > = new Subject ( ) ;
256+ /**
257+ * Stream of events that will fire when one of the options is clicked.
258+ * @deprecated
259+ * Use nb-select (selected) binding to track selection change and <nb-option (click)=""> to track option click.
260+ * @breaking -change 4.0.0
261+ **/
259262 readonly selectionChange : Observable < NbOptionComponent < T > > = this . selectionChange$ . asObservable ( ) ;
260263
261264 protected ref : NbOverlayRef ;
@@ -339,7 +342,7 @@ export class NbSelectComponent<T> implements OnInit, AfterViewInit, AfterContent
339342
340343 this . subscribeOnTriggers ( ) ;
341344 this . subscribeOnPositionChange ( ) ;
342- this . subscribeOnSelectionChange ( ) ;
345+ this . subscribeOnOptionClick ( ) ;
343346 }
344347
345348 ngOnDestroy ( ) {
@@ -395,7 +398,7 @@ export class NbSelectComponent<T> implements OnInit, AfterViewInit, AfterContent
395398 /**
396399 * Selects option or clear all selected options if value is null.
397400 * */
398- protected handleSelect ( option : NbOptionComponent < T > ) {
401+ protected handleOptionClick ( option : NbOptionComponent < T > ) {
399402 if ( option . value ) {
400403 this . selectOption ( option ) ;
401404 } else {
@@ -505,19 +508,24 @@ export class NbSelectComponent<T> implements OnInit, AfterViewInit, AfterContent
505508 } ) ;
506509 }
507510
508- protected subscribeOnSelectionChange ( ) {
509- this . subscribeOnOptionsSelectionChange ( ) ;
511+ protected subscribeOnOptionClick ( ) {
510512 /**
511513 * If the user changes provided options list in the runtime we have to handle this
512514 * and resubscribe on options selection changes event.
513515 * Otherwise, the user will not be able to select new options.
514516 * */
515517 this . options . changes
516- . subscribe ( ( ) => this . subscribeOnOptionsSelectionChange ( ) ) ;
517-
518- this . selectionChange
519- . pipe ( takeWhile ( ( ) => this . alive ) )
520- . subscribe ( ( option : NbOptionComponent < T > ) => this . handleSelect ( option ) ) ;
518+ . pipe (
519+ startWith ( this . options ) ,
520+ switchMap ( ( options : QueryList < NbOptionComponent < T > > ) => {
521+ return merge ( ...options . map ( option => option . click ) ) ;
522+ } ) ,
523+ takeWhile ( ( ) => this . alive ) ,
524+ )
525+ . subscribe ( ( clickedOption : NbOptionComponent < T > ) => {
526+ this . handleOptionClick ( clickedOption ) ;
527+ this . selectionChange$ . next ( clickedOption ) ;
528+ } ) ;
521529 }
522530
523531 protected getContainer ( ) {
@@ -550,20 +558,21 @@ export class NbSelectComponent<T> implements OnInit, AfterViewInit, AfterContent
550558 throw new Error ( 'Can\'t assign array if select is not marked as multiple' ) ;
551559 }
552560
553- this . cleanSelection ( ) ;
561+ const previouslySelectedOptions = this . selectionModel ;
562+ this . selectionModel = [ ] ;
554563
555564 if ( isArray ) {
556565 ( < T [ ] > value ) . forEach ( ( option : T ) => this . selectValue ( option ) ) ;
557566 } else {
558567 this . selectValue ( < T > value ) ;
559568 }
560569
561- this . cd . markForCheck ( ) ;
562- }
570+ // find options which were selected before and trigger deselect
571+ previouslySelectedOptions
572+ . filter ( ( option : NbOptionComponent < T > ) => ! this . selectionModel . includes ( option ) )
573+ . forEach ( ( option : NbOptionComponent < T > ) => option . deselect ( ) ) ;
563574
564- protected cleanSelection ( ) {
565- this . selectionModel . forEach ( ( option : NbOptionComponent < T > ) => option . deselect ( ) ) ;
566- this . selectionModel = [ ] ;
575+ this . cd . markForCheck ( ) ;
567576 }
568577
569578 /**
@@ -591,10 +600,4 @@ export class NbSelectComponent<T> implements OnInit, AfterViewInit, AfterContent
591600 protected isClickedWithinComponent ( $event : Event ) {
592601 return this . hostRef . nativeElement === $event . target || this . hostRef . nativeElement . contains ( $event . target as Node ) ;
593602 }
594-
595- protected subscribeOnOptionsSelectionChange ( ) {
596- merge ( ...this . options . map ( it => it . selectionChange ) )
597- . pipe ( takeWhile ( ( ) => this . alive ) )
598- . subscribe ( ( change : NbOptionComponent < T > ) => this . selectionChange$ . next ( change ) ) ;
599- }
600603}
0 commit comments