44 */
55
66import {
7+ AfterViewInit ,
78 ChangeDetectionStrategy ,
89 ChangeDetectorRef ,
910 Component ,
11+ ElementRef ,
1012 EventEmitter ,
1113 Input ,
14+ NgZone ,
1215 Output ,
16+ QueryList ,
1317 TemplateRef ,
18+ ViewChildren ,
1419 ViewEncapsulation
1520} from '@angular/core' ;
21+ import { fromEvent , merge , Observable } from 'rxjs' ;
22+ import { startWith , switchMap } from 'rxjs/operators' ;
1623
1724import { TransferDirection , TransferItem } from './interface' ;
1825
@@ -30,10 +37,10 @@ import { TransferDirection, TransferItem } from './interface';
3037 [ngClass]="{ 'ant-transfer-list-content-item-disabled': disabled || item.disabled }"
3138 >
3239 <label
40+ #checkboxes
3341 nz-checkbox
3442 [nzChecked]="item.checked"
3543 (nzCheckedChange)="onItemSelect(item)"
36- (click)="$event.stopPropagation()"
3744 [nzDisabled]="disabled || item.disabled"
3845 >
3946 <ng-container *ngIf="!render; else renderContainer">{{ item.title }}</ng-container>
@@ -111,7 +118,7 @@ import { TransferDirection, TransferItem } from './interface';
111118 '[class.ant-transfer-list-with-footer]' : '!!footer'
112119 }
113120} )
114- export class NzTransferListComponent {
121+ export class NzTransferListComponent implements AfterViewInit {
115122 // #region fields
116123
117124 @Input ( ) direction : TransferDirection = 'left' ;
@@ -138,6 +145,8 @@ export class NzTransferListComponent {
138145 @Output ( ) readonly handleSelect : EventEmitter < TransferItem > = new EventEmitter ( ) ;
139146 @Output ( ) readonly filterChange : EventEmitter < { direction : TransferDirection ; value : string } > = new EventEmitter ( ) ;
140147
148+ @ViewChildren ( 'checkboxes' , { read : ElementRef } ) checkboxes ! : QueryList < ElementRef < HTMLLabelElement > > ;
149+
141150 stat = {
142151 checkAll : false ,
143152 checkHalf : false ,
@@ -203,10 +212,33 @@ export class NzTransferListComponent {
203212
204213 // #endregion
205214
206- constructor ( private cdr : ChangeDetectorRef ) { }
215+ constructor ( private ngZone : NgZone , private cdr : ChangeDetectorRef ) { }
207216
208217 markForCheck ( ) : void {
209218 this . updateCheckStatus ( ) ;
210219 this . cdr . markForCheck ( ) ;
211220 }
221+
222+ ngAfterViewInit ( ) : void {
223+ this . checkboxes . changes
224+ . pipe (
225+ startWith ( this . checkboxes ) ,
226+ switchMap ( ( ) => {
227+ const checkboxes = this . checkboxes . toArray ( ) ;
228+ // Caretaker note: we explicitly should call `subscribe()` within the root zone.
229+ // `runOutsideAngular(() => fromEvent(...))` will just create an observable within the root zone,
230+ // but `addEventListener` is called when the `fromEvent` is subscribed.
231+ return new Observable < MouseEvent > ( subscriber =>
232+ this . ngZone . runOutsideAngular ( ( ) =>
233+ merge ( ...checkboxes . map ( checkbox => fromEvent < MouseEvent > ( checkbox . nativeElement , 'click' ) ) ) . subscribe (
234+ subscriber
235+ )
236+ )
237+ ) ;
238+ } )
239+ )
240+ . subscribe ( event => {
241+ event . stopPropagation ( ) ;
242+ } ) ;
243+ }
212244}
0 commit comments