8000 fix(thy-custom-select): fix thyMode action cant't dynamic change · atinc/ngx-tethys@47c161e · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 47c161e

Browse files
committed
fix(thy-custom-select): fix thyMode action cant't dynamic change
1 parent 97d600e commit 47c161e

File tree

4 files changed

+254
-14
lines changed

4 files changed

+254
-14
lines changed

demo/src/app/components/+select/select-section.component.html

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,22 @@ <h2>Select</h2>
1616

1717
<section>
1818
<div class="header">
19-
<h2>多选</h2>
19+
<label
20+
thyCheckbox
21+
[(ngModel)]="multiple"
22+
(ngModelChange)="multipleStatusChange($event)"
23+
thyLabelText="多选"
24+
></label>
2025
</div>
2126
<div class="body">
2227
<div class="demo-select">
23-
<thy-custom-select thyMode="multiple" thySize="md" thyEmptyStateText="无匹配结果">
28+
<thy-custom-select
29+
[(ngModel)]="thyModeValue"
30+
[thyMode]="multiple"
31+
thySize="md"
32+
thyEmptyStateText="无匹配结果"
33+
(ngModelChange)="ngModelChange($event)"
34+
>
2435
<thy-option
2536
*ngFor="let option of optionData"
2637
[thyValue]="option"

demo/src/app/components/+select/select-section.component.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export class DemoSelectSectionComponent implements OnInit {
1616

1717
allowClear = false;
1818

19+
multiple = 'multiple';
20+
1921
page = 0;
2022

2123
emptyModalValue = '';
@@ -44,6 +46,8 @@ export class DemoSelectSectionComponent implements OnInit {
4446

4547
errorSelectedItem = {};
4648

49+
thyModeValue: any = null;
50+
4751
public apiParameters = [
4852
{
4953
property: 'thySize',
@@ -221,6 +225,10 @@ export class DemoSelectSectionComponent implements OnInit {
221225
}
222226
}
223227

228+
ngModelChange(data) {
229+
F438 console.log(data);
230+
}
231+
224232
_fetchOptions() {
225233
this.loading = true;
226234
return timer(1000).pipe(
@@ -277,6 +285,14 @@ export class DemoSelectSectionComponent implements OnInit {
277285
);
278286
}
279287

288+
multipleStatusChange(value: boolean) {
289+
if (value) {
290+
this.multiple = 'multiple';
291+
} else {
292+
this.multiple = '';
293+
}
294+
}
295+
280296
ngOnInit() {
281297
this.page++;
282298
this._fetchOptions().subscribe(() => {

src/select/custom-select.component.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ import {
3434
import { inputValueToBoolean, isArray } from '../util/helpers';
3535
import { ScrollStrategy, Overlay, ViewportRuler, ConnectionPositionPair, ScrollDispatcher } from '@angular/cdk/overlay';
3636
import { CdkScrollable } from '@angular/cdk/scrolling';
37-
import { takeUntil, startWith, take, switchMap, skip, debounceTime } from 'rxjs/operators';
38-
import { Subject, Observable, merge, defer, empty, fromEvent, Subscription } from 'rxjs';
37+
import { takeUntil, startWith, take, switchMap } from 'rxjs/operators';
38+
import { Subject, Observable, merge, defer } from 'rxjs';
3939
import { EXPANDED_DROPDOWN_POSITIONS } from '../core/overlay/overlay-opsition-map';
4040
import { ThySelectOptionGroupComponent } from './option-group.component';
4141
import { SelectionModel } from '@angular/cdk/collections';
@@ -90,7 +90,7 @@ export class ThySelectCustomComponent
9090

9191
_size: InputSize;
9292

93-
_mode: SelectMode;
93+
_mode: SelectMode = '';
9494

9595
_emptyStateText = '没有任何选项';
9696

@@ -147,6 +147,7 @@ export class ThySelectCustomComponent
147147
@Input()
148148
set thyMode(value: SelectMode) {
149149
this._mode = value;
150+
this._instanceSelectionModel();
150151
}
151152

152153
get thyMode(): SelectMode {
@@ -270,7 +271,9 @@ export class ThySelectCustomComponent
270271
this.changeDetectorRef.markForCheck();
271272
}
272273
});
273-
this._instanceSelectionModel();
274+
if (!this._selectionModel) {
275+
this._instanceSelectionModel();
276+
}
274277
if (this._size) {
275278
this._classNames.push(`thy-select-${this._size}`);
276279
}
@@ -281,10 +284,6 @@ export class ThySelectCustomComponent
281284
}
282285

283286
ngAfterContentInit() {
284-
this._selectionModel.onChange.pipe(takeUntil(this._destroy$)).subscribe(event => {
285-
event.added.forEach(option => option.select());
286-
event.removed.forEach(option => option.deselect());
287-
});
288287
this.options.changes
289288
.pipe(
290289
startWith(null),
@@ -426,7 +425,20 @@ export class ThySelectCustomComponent
426425
}
427426

428427
private _instanceSelectionModel() {
429-
this._selectionModel = new SelectionModel<ThyOptionComponent>(this._mode === 'multiple');
428+
if (this._selectionModel) {
429+
this._selectionModel.clear();
430+
this._selectionModel = new SelectionModel<ThyOptionComponent>(this._mode === 'multiple');
431+
this._selectionModel.onChange.pipe(takeUntil(this._destroy$)).subscribe(event => {
432+
event.added.forEach(option => option.select());
433+
event.removed.forEach(option => option.deselect());
434+
});
435+
} else {
436+
this._selectionModel = new SelectionModel<ThyOptionComponent>(this._mode === 'multiple');
437+
this._selectionModel.onChange.pipe(takeUntil(this._destroy$)).subscribe(event => {
438+
event.added.forEach(option => option.select());
439+
event.removed.forEach(option => option.deselect());
440+
});
441+
}
430442
}
431443

432444
_onSelect(option: ThyOptionComponent, event?: Event) {

src/select/custom-select.spec.ts

Lines changed: 204 additions & 3 deletions
-
describe('cselect expand status change', () => {});
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
import { FormsModule, FormControl, ReactiveFormsModule } from '@angular/forms';
1212
import { Component, ViewChild, ViewChildren, QueryList, ElementRef } from '@angular/core';
1313
import { ThySelectModule } from './module';
14-
import { ThySelectCustomComponent } from './custom-select.component';
14+
import { ThySelectCustomComponent, SelectMode } from './custom-select.component';
1515
import { ThyOptionComponent } from './option.component';
1616
import { By } from '@angular/platform-browser';
1717
import { UpdateHostClassService } from '../shared';
@@ -576,7 +576,7 @@ describe('ThyCustomSelect', () => {
576576
expect(fixture.componentInstance.select.panelOpen).toBe(true);
577577
expect(overlayContainerElement.textContent).toContain('Pizza');
578578
}));
579-
it('shoule close select when mouse leave select-container', fakeAsync(() => {
579+
it('should close select when mouse leave select-container', fakeAsync(() => {
580580
const fixture = TestBed.createComponent(SelectWithHoverTriggerComponent);
581581
fixture.detectChanges();
582582
const select = fixture.debugElement.nativeElement.querySelector('thy-custom-select');
@@ -595,7 +595,180 @@ describe('ThyCustomSelect', () => {
595595
}));
596596
});
597597

598
598+
describe('thyMode logic', () => {
599+
beforeEach(async(() => {
600+
configureThyCustomSelectTestingModule([SelectWithThyModeComponent]);
601+
}));
602+
it('should not close the panel when an item is clicked and thyMode is multiple', fakeAsync(() => {
603+
const fixture = TestBed.createComponent(SelectWithThyModeComponent);
604+
fixture.detectChanges();
605+
const trigger = fixture.debugElement.query(By.css('.form-control-custom')).nativeElement;
606+
607+
trigger.click();
608+
fixture.detectChanges();
609+
flush();
610+
611+
const option = overlayContainerElement.querySelector('thy-option') as HTMLElement;
612+
option.click();
613+
fixture.detectChanges();
614+
flush();
615+
616+
expect(fixture.componentInstance.select.panelOpen).toBe(true);
617+
}));
618+
619+
it('should close expand when thyMode change to empty', fakeAsync(() => {
620+
const fixture = TestBed.createComponent(SelectWithThyModeComponent);
621+
fixture.detectChanges();
622+
fixture.componentInstance.selectMode = '';
623+
fixture.detectChanges();
624+
flush();
625+
626+
const trigger = fixture.debugElement.query(By.css('.form-control-custom')).nativeElement;
627+
trigger.click();
628+
fixture.detectChanges();
629+
flush();
630+
631+
const option = overlayContainerElement.querySelector('thy-option') as HTMLElement;
632+
option.click();
633+
fixture.detectChanges();
634+
flush();
635+
636+
expect(fixture.componentInstance.select.panelOpen).toBe(false);
637+
}));
638+
639+
it('should clear selected status when thyMode change', fakeAsync(() => {
640+
const fixture = TestBed.createComponent(SelectWithThyModeComponent);
641+
fixture.detectChanges();
642+
643+
const trigger = fixture.debugElement.query(By.css('.form-control-custom')).nativeElement;
644+
trigger.click();
645+
fixture.detectChanges();
646+
flush();
647+
648+
const optionComponents = fixture.componentInstance.options.toArray();
649+
const options = overlayContainerElement.querySelectorAll('thy-option');
650+
651+
(options.item(0) as HTMLElement).click();
652+
(options.item(1) as HTMLElement).click();
653+
654+
const backdrop = overlayContainerElement.querySelector('.cdk-overlay-backdrop') as HTMLElement;
655+
backdrop.click();
656+
657+
fixture.detectChanges();
658+
flush();
659+
660+
expect(optionComponents[0].selected).toBe(true);
661+
expect(optionComponents[1].selected).toBe(true);
662+
663+
fixture.componentInstance.selectMode = '';
664+
fixture.detectChanges();
665+
flush();
666+
667+
expect(optionComponents[0].selected).toBe(false);
668+
expect(optionComponents[1].selected).toBe(false);
669+
670+
trigger.click();
671+
fixture.detectChanges();
672+
flush();
673+
(options.item(0) as HTMLElement).click();
674+
expect(optionComponents[0].selected).toBe(true);
675+
676+
fixture.componentInstance.selectMode = 'multiple';
677+
fixture.detectChanges();
678+
flush();
679+
680+
expect(optionComponents[0].selected).toBe(false);
681+
}));
682+
683+
it('should not clear status when the thyMode value is not change', fakeAsync(() => {
684+
const fixture = TestBed.createComponent(SelectWithThyModeComponent);
685+
fixture.detectChanges();
686+
687+
const trigger = fixture.debugElement.query(By.css('.form-control-custom')).nativeElement;
688+
trigger.click();
689+
fixture.detectChanges();
690+
flush();
691+
692+
const optionComponents = fixture.componentInstance.options.toArray();
693+
const options = overlayContainerElement.querySelectorAll('thy-option');
694+
695+
(options.item(0) as HTMLElement).click();
696+
(options.item(1) as HTMLElement).click();
697+
698+
const backdrop = overlayContainerElement.querySelector('.cdk-overlay-backdrop') as HTMLElement;
699+
backdrop.click();
700+
701+
fixture.detectChanges();
702+
flush();
703+
704+
expect(optionComponents[0].selected).toBe(true);
705+
expect(optionComponents[1].selected).toBe(true);
706+
707+
fixture.componentInstance.selectMode = 'multiple';
708+
fixture.detectChanges();
709+
flush();
710+
711+
expect(optionComponents[0].selected).toBe(true);
712+
expect(optionComponents[1].selected).toBe(true);
713+
}));
714+
715+
it('should apply default mode when thyMode change to empty', fakeAsync(() => {
716+
const fixture = TestBed.createComponent(SelectWithThyModeComponent);
717+
fixture.detectChanges();
718+
fixture.componentInstance.selectMode = '';
719+
fixture.detectChanges();
720+
flush();
721+
722+
const trigger = fixture.debugElement.query(By.css('.form-control-custom')).nativeElement;
723+
trigger.click();
724+
fixture.detectChanges();
725+
flush();
726+
727+
const options = overlayContainerElement.querySelectorAll('thy-option');
728+
(options.item(0) as HTMLElement).click();
729+
fixture.detectChanges();
730+
flush();
731+
const optionComponents = fixture.componentInstance.options.toArray();
732+
expect(optionComponents[0].selected).toBe(true);
733+
(options.item(1) as HTMLElement).click();
734+
fixture.detectChanges();
735+
flush();
736+
expect(optionComponents[0].selected).toBe(false);
737+
expect(optionComponents[1].selected).toBe(true);
738+
}));
739+
740+
it('should apply multiple mode when thyMode change to multiple', fakeAsync(() => {
741+
const fixture = TestBed.createComponent(SelectWithThyModeComponent);
742+
fixture.detectChanges();
743+
fixture.componentInstance.selectMode = '';
744+
fixture.detectChanges();
745+
flush();
746+
747+
const trigger = fixture.debugElement.query(By.css('.form-control-custom')).nativeElement;
748+
trigger.click();
749+
fixture.detectChanges();
750+
flush();
751+
752+
const options = overlayContainerElement.querySelectorAll('thy-option');
753+
(options.item(0) as HTMLElement).click();
754+
fixture.detectChanges();
755+
flush();
756+
757+
fixture.componentInstance.selectMode = 'multiple';
758+
fixture.detectChanges();
759+
flush();
760+
761+
const optionComponents = fixture.componentInstance.options.toArray();
762+
763+
(options.item(0) as HTMLElement).click();
764+
(options.item(1) as HTMLElement).click();
765+
fixture.detectChanges();
766+
flush();
767+
768+
expect(optionComponents[0].selected).toBe(true);
769+
expect(optionComponents[1].selected).toBe(true);
770+
}));
771+
});
599772
});
600773

601774
@Component({
@@ -961,3 +1134,31 @@ class SelectWithExpandStatusComponent {
9611134
thyOnExpandStatusChange = jasmine.createSpy('thyOnExpandStatusChange callback');
9621135
@ViewChild(ThySelectCustomComponent) select: ThySelectCustomComponent;
9631136
}
1137+
1138+
@Component({
1139+
template: `
1140+
<form thyForm name="demoForm" #demoForm="ngForm">
1141+
<thy-custom-select placeholder="Food" [(ngModel)]="selectedFoods" name="food" [thyMode]="selectMode">
1142+
<thy-option
1143+
*ngFor="let food of foods"
1144+
[thyValue]="food.value"
1145+
[thyLabelText]="food.viewValue"
1146+
></thy-option>
1147+
</thy-custom-select>
1148+
</form>
1149+
`
1150+
})
1151+
class SelectWithThyModeComponent {
1152+
foods: any[] = [
1153+
{ value: ['steak-0', 'steak-1'], viewValue: 'Steak' },
1154+
{ value: ['pizza-1', 'pizza-2'], viewValue: 'Pizza' },
1155+
{ value: ['tacos-2', 'tacos-3'], viewValue: 'Tacos' }
1156+
];
1157+
1158+
selectMode: SelectMode = 'multiple';
1159+
1160+
selectedFoods = null;
1161+
1162+
@ViewChild(ThySelectCustomComponent) select: ThySelectCustomComponent;
1163+
@ViewChildren(ThyOptionComponent) options: QueryList<ThyOptionComponent>;
1164+
}

0 commit comments

Comments
 (0)
0