Skip to content

Commit

Permalink
Merge pull request #982 from ng-select/selected-fix
Browse files Browse the repository at this point in the history
fix: map selected items while source changed
  • Loading branch information
varnastadeus committed Dec 5, 2018
2 parents 72d2254 + c5bfd3f commit 6d39655
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 26 deletions.
11 changes: 8 additions & 3 deletions demo/app/app.component.ts
@@ -1,9 +1,10 @@
import '../style/styles.scss';

import { Component, ChangeDetectionStrategy } from '@angular/core';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { Title } from '@angular/platform-browser';
import { filter, map, mergeMap } from 'rxjs/operators';
import { NgSelectConfig } from '../../src';

@Component({
selector: 'demo-app',
Expand All @@ -17,9 +18,13 @@ export class AppComponent {
exampleSourceUrl: string;
dir: 'ltr' | 'rtl' = 'ltr';

constructor(private router: Router,
constructor(
private router: Router,
private activatedRoute: ActivatedRoute,
private titleService: Title) {
private titleService: Title,
private config: NgSelectConfig
) {
this.config.placeholder = 'Select item';
}

ngOnInit() {
Expand Down
1 change: 0 additions & 1 deletion demo/app/examples/reactive-forms.component.ts
Expand Up @@ -245,7 +245,6 @@ export class ReactiveFormsComponent {

selectAlbumsRange(from, to) {
this.albums = this.allAlbums.slice(from, to);
this.selectFirstAlbum();
}

openModal(content) {
Expand Down
2 changes: 1 addition & 1 deletion src/ng-select/config.service.ts
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';

@Injectable({providedIn: 'root'})
@Injectable({ providedIn: 'root' })
export class NgSelectConfig {
placeholder: string;
notFoundText = 'No items found';
Expand Down
7 changes: 0 additions & 7 deletions src/ng-select/items-list.ts
Expand Up @@ -237,15 +237,8 @@ export class ItemsList {
mapSelectedItems() {
const multiple = this._ngSelect.multiple;
for (const selected of this.selectedItems) {
if (selected.mapped) {
continue;
}

const value = this._ngSelect.bindValue ? this.resolveNested(selected.value, this._ngSelect.bindValue) : selected.value;
const item = this.findItem(value);
if (item) {
item.mapped = true;
}
this._selectionModel.unselect(selected, multiple);
this._selectionModel.select(item || selected, multiple, this._ngSelect.selectableGroupAsModel);
}
Expand Down
1 change: 0 additions & 1 deletion src/ng-select/ng-dropdown-panel.component.ts
Expand Up @@ -212,7 +212,6 @@ export class NgDropdownPanelComponent implements OnInit, OnChanges, OnDestroy, A
}

const path = $event.path || ($event.composedPath && $event.composedPath());

if ($event.target && $event.target.shadowRoot && path && path[0] && this._select.contains(path[0])) {
return;
}
Expand Down
36 changes: 29 additions & 7 deletions src/ng-select/ng-select.component.spec.ts
Expand Up @@ -335,6 +335,30 @@ describe('NgSelectComponent', function () {
expect(fixture.componentInstance.selectedCity).toBeNull();
}));

it('should map selected items with items in dropdown', fakeAsync(() => {
const fixture = createTestingModule(
NgSelectTestCmp,
`<ng-select [items]="cities"
bindLabel="name"
[clearable]="true"
[(ngModel)]="selectedCity">
</ng-select>`);

select = fixture.componentInstance.select;

fixture.componentInstance.selectedCity = fixture.componentInstance.cities[0];
tickAndDetectChanges(fixture);

fixture.componentInstance.cities = [...fixture.componentInstance.cities];
tickAndDetectChanges(fixture);

fixture.componentInstance.cities = [...fixture.componentInstance.cities];
tickAndDetectChanges(fixture);

expect(fixture.componentInstance.selectedCity).toEqual(fixture.componentInstance.cities[0]);
expect(select.itemsList.filteredItems[0].selected).toBeTruthy();
}));

it('should clear previous single select value when setting new model', fakeAsync(() => {
const fixture = createTestingModule(
NgSelectTestCmp,
Expand Down Expand Up @@ -422,7 +446,7 @@ describe('NgSelectComponent', function () {
expect(fixture.componentInstance.select.itemsList.markedItem.value).toEqual({ name: 'Vilnius', id: 1 });
}));

it('bind to custom object properties', fakeAsync(() => {
it('should bind to custom object properties', fakeAsync(() => {
const fixture = createTestingModule(
NgSelectTestCmp,
`<ng-select [items]="cities"
Expand All @@ -431,20 +455,18 @@ describe('NgSelectComponent', function () {
[(ngModel)]="selectedCityId">
</ng-select>`);

// from component to model
selectOption(fixture, KeyCode.ArrowDown, 0);
tickAndDetectChanges(fixture);
expect(fixture.componentInstance.selectedCityId).toEqual(1);

// from model to component
fixture.componentInstance.selectedCityId = 2;
tickAndDetectChanges(fixture);
expect(fixture.componentInstance.select.selectedItems).toEqual([jasmine.objectContaining({
value: fixture.componentInstance.cities[1]
})]);
}));

it('bind to nested label property', fakeAsync(() => {
it('should bind to nested label property', fakeAsync(() => {
const fixture = createTestingModule(
NgSelectTestCmp,
`<ng-select [items]="countries"
Expand All @@ -467,7 +489,7 @@ describe('NgSelectComponent', function () {
})]);
}));

it('bind to nested value property', fakeAsync(() => {
it('should bind bind to nested value property', fakeAsync(() => {
const fixture = createTestingModule(
NgSelectTestCmp,
`<ng-select [items]="countries"
Expand All @@ -492,7 +514,7 @@ describe('NgSelectComponent', function () {
expect(fixture.componentInstance.selectedCountry).toEqual('b');
}));

it('bind to simple array', fakeAsync(() => {
it('should bind to simple array', fakeAsync(() => {
const fixture = createTestingModule(
NgSelectTestCmp,
`<ng-select [items]="citiesNames"
Expand All @@ -508,7 +530,7 @@ describe('NgSelectComponent', function () {
.toEqual([jasmine.objectContaining({ label: 'Kaunas', value: 'Kaunas' })]);
}));

it('bind to object', fakeAsync(() => {
it('should bind to object', fakeAsync(() => {
const fixture = createTestingModule(
NgSelectTestCmp,
`<ng-select [items]="cities"
Expand Down
10 changes: 5 additions & 5 deletions src/ng-select/ng-select.component.ts
Expand Up @@ -174,7 +174,7 @@ export class NgSelectComponent implements OnDestroy, OnChanges, AfterViewInit, C

private readonly _destroy$ = new Subject<void>();
private readonly _keyPress$ = new Subject<string>();
private _onChange = (_: NgOption) => { };
private _onChange = (_: any) => { };
private _onTouched = () => { };

clearItem = (item: any) => {
Expand Down Expand Up @@ -661,13 +661,13 @@ export class NgSelectComponent implements OnDestroy, OnChanges, AfterViewInit, C
const model = [];
for (const item of this.selectedItems) {
if (this.bindValue) {
let resolvedValue = null;
let value = null;
if (item.children) {
resolvedValue = item.value[<string>this.groupBy];
value = item.value[<string>this.groupBy];
} else {
resolvedValue = this.itemsList.resolveNested(item.value, this.bindValue);
value = this.itemsList.resolveNested(item.value, this.bindValue);
}
model.push(resolvedValue);
model.push(value);
} else {
model.push(item.value);
}
Expand Down
1 change: 0 additions & 1 deletion src/ng-select/ng-select.types.ts
Expand Up @@ -2,7 +2,6 @@ export interface NgOption {
[name: string]: any;
index?: number;
htmlId?: string;
mapped?: boolean;
selected?: boolean;
disabled?: boolean;
marked?: boolean;
Expand Down

0 comments on commit 6d39655

Please sign in to comment.