@@ -26,7 +26,7 @@ import {
26
26
} from '@angular/core' ;
27
27
import { ControlValueAccessor , NG_VALUE_ACCESSOR } from '@angular/forms' ;
28
28
import { merge , Observable , Subject } from 'rxjs' ;
29
- import { takeWhile } from 'rxjs/operators' ;
29
+ import { startWith , switchMap , takeWhile } from 'rxjs/operators' ;
30
30
31
31
import {
32
32
NbAdjustableConnectedPositionStrategy ,
@@ -252,10 +252,13 @@ export class NbSelectComponent<T> implements OnInit, AfterViewInit, AfterContent
252
252
*/
253
253
overlayPosition : NbPosition = '' as NbPosition ;
254
254
255
- /**
256
- * Stream of events that will fire when one of the options fire selectionChange event.
257
- * */
258
255
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
+ **/
259
262
readonly selectionChange : Observable < NbOptionComponent < T > > = this . selectionChange$ . asObservable ( ) ;
260
263
261
264
protected ref : NbOverlayRef ;
@@ -339,7 +342,7 @@ export class NbSelectComponent<T> implements OnInit, AfterViewInit, AfterContent
339
342
340
343
this . subscribeOnTriggers ( ) ;
341
344
this . subscribeOnPositionChange ( ) ;
342
- this . subscribeOnSelectionChange ( ) ;
345
+ this . subscribeOnOptionClick ( ) ;
343
346
}
344
347
345
348
ngOnDestroy ( ) {
@@ -395,7 +398,7 @@ export class NbSelectComponent<T> implements OnInit, AfterViewInit, AfterContent
395
398
/**
396
399
* Selects option or clear all selected options if value is null.
397
400
* */
398
- protected handleSelect ( option : NbOptionComponent < T > ) {
401
+ protected handleOptionClick ( option : NbOptionComponent < T > ) {
399
402
if ( option . value ) {
400
403
this . selectOption ( option ) ;
401
404
} else {
@@ -505,19 +508,24 @@ export class NbSelectComponent<T> implements OnInit, AfterViewInit, AfterContent
505
508
} ) ;
506
509
}
507
510
508
- protected subscribeOnSelectionChange ( ) {
509
- this . subscribeOnOptionsSelectionChange ( ) ;
511
+ protected subscribeOnOptionClick ( ) {
510
512
/**
511
513
* If the user changes provided options list in the runtime we have to handle this
512
514
* and resubscribe on options selection changes event.
513
515
* Otherwise, the user will not be able to select new options.
514
516
* */
515
517
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
+ } ) ;
521
529
}
522
530
523
531
protected getContainer ( ) {
@@ -550,20 +558,21 @@ export class NbSelectComponent<T> implements OnInit, AfterViewInit, AfterContent
550
558
throw new Error ( 'Can\'t assign array if select is not marked as multiple' ) ;
551
559
}
552
560
553
- this . cleanSelection ( ) ;
561
+ const previouslySelectedOptions = this . selectionModel ;
562
+ this . selectionModel = [ ] ;
554
563
555
564
if ( isArray ) {
556
565
( < T [ ] > value ) . forEach ( ( option : T ) => this . selectValue ( option ) ) ;
557
566
} else {
558
567
this . selectValue ( < T > value ) ;
559
568
}
560
569
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 ( ) ) ;
563
574
564
- protected cleanSelection ( ) {
565
- this . selectionModel . forEach ( ( option : NbOptionComponent < T > ) => option . deselect ( ) ) ;
566
- this . selectionModel = [ ] ;
575
+ this . cd . markForCheck ( ) ;
567
576
}
568
577
569
578
/**
@@ -591,10 +600,4 @@ export class NbSelectComponent<T> implements OnInit, AfterViewInit, AfterContent
591
600
protected isClickedWithinComponent ( $event : Event ) {
592
601
return this . hostRef . nativeElement === $event . target || this . hostRef . nativeElement . contains ( $event . target as Node ) ;
593
602
}
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
- }
600
603
}
0 commit comments