From 664286e5a799909d8011ce9462f677cfe54832ea Mon Sep 17 00:00:00 2001 From: Allan Goncalves Date: Mon, 17 Sep 2018 13:27:05 -0400 Subject: [PATCH] fix(sort): display mat-sort-header arrow when sorting programmatically Fix mat-sort-header arrow not displaying after sorting programmatically (eg. `matSort.sort()`) Related to #10242, #12754 --- src/material/sort/sort-header.ts | 48 +++++++++++++++----------------- src/material/sort/sort.spec.ts | 13 +++++++++ 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/material/sort/sort-header.ts b/src/material/sort/sort-header.ts index 1fc2e46f7916..18abebb3d47d 100644 --- a/src/material/sort/sort-header.ts +++ b/src/material/sort/sort-header.ts @@ -20,6 +20,7 @@ import { } from '@angular/core'; import {CanDisable, CanDisableCtor, mixinDisabled} from '@angular/material/core'; import {merge, Subscription} from 'rxjs'; +import {filter} from 'rxjs/operators'; import {MatSort, MatSortable} from './sort'; import {matSortAnimations} from './sort-animations'; import {SortDirection} from './sort-direction'; @@ -152,19 +153,28 @@ export class MatSortHeader extends _MatSortHeaderMixinBase } this._rerenderSubscription = merge(_sort.sortChange, _sort._stateChanges, _intl.changes) - .subscribe(() => { - if (this._isSorted()) { - this._updateArrowDirection(); - } - - // If this header was recently active and now no longer sorted, animate away the arrow. - if (!this._isSorted() && this._viewState && this._viewState.toState === 'active') { - this._disableViewStateAnimation = false; - this._setAnimationTransitionState({fromState: 'active', toState: this._arrowDirection}); - } - - changeDetectorRef.markForCheck(); - }); + .pipe(filter(() => !!this.id)) + .subscribe(() => { + const viewState = this._viewState; + + // Do not show the animation if the header was already shown in the right position. + if (viewState && viewState.toState === 'hint' || viewState.toState === 'active') { + this._disableViewStateAnimation = true; + } + + if (this._isSorted()) { + this._updateArrowDirection(); + + this._setAnimationTransitionState({fromState: this._arrowDirection, toState: 'active'}); + } else if (viewState && viewState.toState === 'active') { + // This header was recently active and now no longer sorted, animate away the arrow. + this._disableViewStateAnimation = false; + + this._setAnimationTransitionState({fromState: 'active', toState: this._arrowDirection}); + } + + changeDetectorRef.markForCheck(); + }); } ngOnInit() { @@ -226,18 +236,6 @@ export class MatSortHeader extends _MatSortHeaderMixinBase this._sort.sort(this); - // Do not show the animation if the header was already shown in the right position. - if (this._viewState.toState === 'hint' || this._viewState.toState === 'active') { - this._disableViewStateAnimation = true; - } - - // If the arrow is now sorted, animate the arrow into place. Otherwise, animate it away into - // the direction it is facing. - const viewState: ArrowViewStateTransition = this._isSorted() ? - {fromState: this._arrowDirection, toState: 'active'} : - {fromState: 'active', toState: this._arrowDirection}; - this._setAnimationTransitionState(viewState); - this._showIndicatorHint = false; } diff --git a/src/material/sort/sort.spec.ts b/src/material/sort/sort.spec.ts index 2822fdccf83f..82a5085cc063 100644 --- a/src/material/sort/sort.spec.ts +++ b/src/material/sort/sort.spec.ts @@ -188,6 +188,19 @@ describe('MatSort', () => { component.expectViewAndDirectionStates(expectedStates); }); + it('should be correct when sort has changed programmatically while a header is active', () => { + // Sort the first header to set up + component.sort('defaultA'); + expectedStates.set('defaultA', {viewState: 'asc-to-active', arrowDirection: 'active-asc'}); + component.expectViewAndDirectionStates(expectedStates); + + // Sort the second header programmatically and verify that the first header animated away + component.matSort.sort({id: 'defaultB', start: 'asc', disableClear: false}); + expectedStates.set('defaultA', {viewState: 'active-to-asc', arrowDirection: 'asc'}); + expectedStates.set('defaultB', {viewState: 'asc-to-active', arrowDirection: 'active-asc'}); + component.expectViewAndDirectionStates(expectedStates); + }); + it('should be correct when sort has been disabled', () => { // Mousing over the first sort should set the view state to hint component.disabledColumnSort = true;