Skip to content

Commit 90f7a56

Browse files
crisbetoannieyw
authored andcommitted
fix(material/sort): view not updated when sort state is changed through binding (#19492)
Fixes the visible state of the sort header not being updated if it gets changed through the `matSortActive` binding. Fixes #19467. (cherry picked from commit ca7d379)
1 parent e94b7bd commit 90f7a56

File tree

2 files changed

+38
-25
lines changed

2 files changed

+38
-25
lines changed

src/material/sort/sort-header.ts

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -159,20 +159,7 @@ export class MatSortHeader extends _MatSortHeaderMixinBase
159159
throw getSortHeaderNotContainedWithinSortError();
160160
}
161161

162-
this._rerenderSubscription = merge(_sort.sortChange, _sort._stateChanges, _intl.changes)
163-
.subscribe(() => {
164-
if (this._isSorted()) {
165-
this._updateArrowDirection();
166-
}
167-
168-
// If this header was recently active and now no longer sorted, animate away the arrow.
169-
if (!this._isSorted() && this._viewState && this._viewState.toState === 'active') {
170-
this._disableViewStateAnimation = false;
171-
this._setAnimationTransitionState({fromState: 'active', toState: this._arrowDirection});
172-
}
173-
174-
_changeDetectorRef.markForCheck();
175-
});
162+
this._handleStateChanges();
176163
}
177164

178165
ngOnInit() {
@@ -243,27 +230,17 @@ export class MatSortHeader extends _MatSortHeaderMixinBase
243230

244231
/** Triggers the sort on this sort header and removes the indicator hint. */
245232
_toggleOnInteraction() {
246-
247233
this._sort.sort(this);
248234

249235
// Do not show the animation if the header was already shown in the right position.
250236
if (this._viewState.toState === 'hint' || this._viewState.toState === 'active') {
251237
this._disableViewStateAnimation = true;
252238
}
253-
254-
// If the arrow is now sorted, animate the arrow into place. Otherwise, animate it away into
255-
// the direction it is facing.
256-
const viewState: ArrowViewStateTransition = this._isSorted() ?
257-
{fromState: this._arrowDirection, toState: 'active'} :
258-
{fromState: 'active', toState: this._arrowDirection};
259-
this._setAnimationTransitionState(viewState);
260-
261-
this._showIndicatorHint = false;
262239
}
263240

264241
_handleClick() {
265242
if (!this._isDisabled()) {
266-
this._toggleOnInteraction();
243+
this._sort.sort(this);
267244
}
268245
}
269246

@@ -330,6 +307,32 @@ export class MatSortHeader extends _MatSortHeaderMixinBase
330307
return !this._isDisabled() || this._isSorted();
331308
}
332309

310+
/** Handles changes in the sorting state. */
311+
private _handleStateChanges() {
312+
this._rerenderSubscription =
313+
merge(this._sort.sortChange, this._sort._stateChanges, this._intl.changes).subscribe(() => {
314+
if (this._isSorted()) {
315+
this._updateArrowDirection();
316+
317+
// Do not show the animation if the header was already shown in the right position.
318+
if (this._viewState.toState === 'hint' || this._viewState.toState === 'active') {
319+
this._disableViewStateAnimation = true;
320+
}
321+
322+
this._setAnimationTransitionState({fromState: this._arrowDirection, toState: 'active'});
323+
this._showIndicatorHint = false;
324+
}
325+
326+
// If this header was recently active and now no longer sorted, animate away the arrow.
327+
if (!this._isSorted() && this._viewState && this._viewState.toState === 'active') {
328+
this._disableViewStateAnimation = false;
329+
this._setAnimationTransitionState({fromState: 'active', toState: this._arrowDirection});
330+
}
331+
332+
this._changeDetectorRef.markForCheck();
333+
});
334+
}
335+
333336
static ngAcceptInputType_disableClear: BooleanInput;
334337
static ngAcceptInputType_disabled: BooleanInput;
335338
}

src/material/sort/sort.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,16 @@ describe('MatSort', () => {
198198
component.dispatchMouseEvent('defaultA', 'mouseenter');
199199
component.expectViewAndDirectionStates(expectedStates);
200200
});
201+
202+
it('should be correct when sorting programmatically', () => {
203+
component.active = 'defaultB';
204+
component.direction = 'asc';
205+
fixture.detectChanges();
206+
207+
expectedStates.set('defaultB', {viewState: 'asc-to-active', arrowDirection: 'active-asc'});
208+
component.expectViewAndDirectionStates(expectedStates);
209+
});
210+
201211
});
202212

203213
it('should be able to cycle from asc -> desc from either start point', () => {

0 commit comments

Comments
 (0)