Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force change-detection upon ContentChildren()... #8398

Merged
merged 14 commits into from
Nov 20, 2017

Conversation

actra-gschuster
Copy link
Contributor

...changes like added / remove steps

this._stepChangesSubscription = this._steps.changes.subscribe(() => this._stateChanged());
}
ngOnDestroy() {
if(this._stepChangesSubscription instanceof Subscription) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A pattern we've started using for situations like this is to create a stream that emits on destory and then use takeUntil when describing (e.g. https://github.com/angular/material2/blob/master/src/lib/sidenav/drawer.ts#L467)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So MatStep should emit on destroy and MatStepper should subscribe on each step?
To know which steps exist stepper would have to listen on QueryList changes...
Did I get that correctly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like this, your ngOnDestroy would emit on a subject:

ngOnDestroy() {
  this._destroyed.next();
  this._destroyed.complete();
}

And then you don't have to save the Subscription when you subscribe, you can just use takeUntil:

this._steps.changes.pipe(takeUntil(this._destroyed)).subscribe(() => ...);

This way if we make more subscriptions later on we don't have to save them all as separate member variables

_stepChangesSubscription: Subscription;
ngAfterContentInit() {
this._stepChangesSubscription = this._steps.changes.subscribe(() => this._stateChanged());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: \n

@actra-gschuster
Copy link
Contributor Author

actra-gschuster commented Nov 15, 2017

@mmalerba Applied your suggested changes, added the "emit on destroy" pattern to the upper CDK stepper for other inherited classes to be able to use it without specifying their own _destroy property.

/** Workaround for https://github.com/angular/material2/issues/8397 */
ngAfterContentInit() {
this._steps.changes.pipe(takeUntil(this._destroyed)).subscribe(() => this._stateChanged());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe change the comment to be like this?

ngAfterContentInit() {
  // Mark the component for change detection whenever the content children query changes
  this._steps.changes.pipe(...).subscribe(...);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, fixed.

} from '@angular/core';
import {LEFT_ARROW, RIGHT_ARROW, ENTER, SPACE} from '@angular/cdk/keycodes';
import {CdkStepLabel} from './step-label';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {AbstractControl} from '@angular/forms';
import {Direction, Directionality} from '@angular/cdk/bidi';
import {takeUntil} from 'rxjs/operators/takeUntil';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this import should be in src/lib/stepper/stepper.ts since it isn't used in this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, was a mistake.

Copy link
Contributor

@mmalerba mmalerba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, one more nit

/** The list of step headers of the steps in the stepper. */
@ViewChildren(MatStepHeader, {read: ElementRef}) _stepHeader: QueryList<ElementRef>;

/** Steps that the stepper holds. */
@ContentChildren(MatStep) _steps: QueryList<MatStep>;

/** Mark the component for change detection whenever the content children query changes */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor nit: move this comment inside the method and use // style comment since it describes the reason behind some specific logic, not the purpose of the ngAfterContentInit method

@actra-gschuster
Copy link
Contributor Author

OK, I think we're done now ;-)

@mmalerba mmalerba added pr: lgtm action: merge The PR is ready for merge by the caretaker labels Nov 15, 2017
@mmalerba
Copy link
Contributor

oh it looks like there's some lint errors and you forgot to import Subject, but good to go after that's fixed

@mmalerba mmalerba removed the action: merge The PR is ready for merge by the caretaker label Nov 15, 2017
@mmalerba
Copy link
Contributor

I think you added the import to the wrong file, CI is still red

@actra-gschuster
Copy link
Contributor Author

Woohoo, tests finally passed, linting is very nitpicking about trailing spaces ;-)

@willshowell
Copy link
Contributor

@actra-gschuster for next time, you should be able to set your editor to automatically remove trailing spaces. You can also run tests and lint locally so you don't have to push and wait for travis each time:

npm run test
npm run tslint

@mmalerba mmalerba added the action: merge The PR is ready for merge by the caretaker label Nov 17, 2017
...changes like added / remove steps
Moved step changes subscription to AfterContentInit as it depends on `@ContentChildren`
Now uses "emit on destroy" pattern for stepper
Now uses "emit on destroy" pattern for stepper to subscribe to step changes (fixes angular#8397)
Removed (now) unneccessary Subscription import
Fixed missing import
@jelbourn jelbourn merged commit 2bc0b41 into angular:master Nov 20, 2017
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 7, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants