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

fix(menu): multiple close events for a single close #6961

Merged
merged 3 commits into from
Sep 12, 2017

Conversation

ppham27
Copy link
Contributor

@ppham27 ppham27 commented Sep 10, 2017

Don't emit a closed event when another event will be emitted. Previously, if one clicked on a menu item, one would get two events: undefined and click in that order. One would see similar behavior for keydown or clicking the backdrop. Unit tests were updated to prevent a regression.

Don't emit a closed event when another event will be emitted. Previously, if one clicked on a menu item, one would get two events: `undefined` and `click` in that order. One would see similar behavior for `keydown` or clicking the backdrop. Unit tests were updated to prevent a regression.
@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Sep 10, 2017
@@ -139,7 +139,7 @@ export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy {
}

/** Event emitted when the menu is closed. */
@Output() close = new EventEmitter<void | 'click' | 'keydown'>();
@Output() close = new EventEmitter<void | 'click' | 'destroy' | 'keydown'>();
Copy link
Member

Choose a reason for hiding this comment

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

The idea with this one was to emit the reason only if it's user-generated. Given that there is no special behavior for destroy, can you revert it back to void | 'click' | 'keydown'?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. I was also wondering if it's a bug that destroy will emit a close event when the menu is already closed?

Copy link
Member

Choose a reason for hiding this comment

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

It's there to notify any child menus to close.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But child menus won't be open unless the menu itself is open? Anyway, I'm more than happy to leave it as it is, as it doesn't really affect any use cases that I can think of.

Copy link
Member

Choose a reason for hiding this comment

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

In most cases the children won't be open without a parent, but it's possible for the parent to be destroyed while the children are still open.

* Gives the option of setting emitEvent to false to avoid emitting an event
* when an event will already be emitted.
*/
private _closeMenu(emitEvent: boolean) {
Copy link
Member

Choose a reason for hiding this comment

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

Rather than having the emitEvent parameter, you can remove the this.menu.close.emit call from here and move it only to closeMenu. Also change the doc string to something along the lines of "Closes the menu and does the necessary cleanup".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Should I only emit the event when the menu is already open, though?

@@ -485,6 +485,7 @@ describe('MdMenu', () => {
fixture = TestBed.createComponent(SimpleMenu);
fixture.detectChanges();
fixture.componentInstance.trigger.openMenu();
fixture.componentInstance.closeCallback.calls.reset();
Copy link
Member

Choose a reason for hiding this comment

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

Why is this necessary? The callbacks should be reset after each test, because the component is re-compiled.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They were necessary when because Observable.of(null) was triggering a close event. Replaced with Observable.empty()

Copy link
Member

Choose a reason for hiding this comment

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

Observable.of(null) will emit null immediately. Observable.of() won't.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are you saying that I should change it to Observable.of() instead of Observable.empty()? To me, Observable.empty() is more readable and makes the intent more clear.

But I don't mind change it to Observable.of() since the behavior would be the same as Observable.empty().

Copy link
Member

Choose a reason for hiding this comment

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

Observable.empty() is definitely valid in this case. I just want to avoid bringing in an extra symbol from RxJS.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to Observable.of()

expect(fixture.componentInstance.closeCallback).toHaveBeenCalledTimes(1);
});

it('should emit an event when escaped', () => {
Copy link
Member

Choose a reason for hiding this comment

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

"should emit an event when pressing ESCAPE".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@@ -989,11 +1004,18 @@ describe('MdMenu', () => {

expect(menus.length).toBe(3, 'Expected three open menus');

instance.rootCloseCallback.calls.reset();
Copy link
Member

Choose a reason for hiding this comment

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

These reset calls shouldn't be necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They were necessary when because Observable.of(null) was triggering a close event. Replaced with Observable.empty()

/**
* Closes the menu and does the necessary cleanup.
*/
private _closeMenu() {
Copy link
Member

Choose a reason for hiding this comment

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

One last nitpick: can you rename this to _destroyMenu to avoid confusion with closeMenu?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

_closeMenu -> _destroyMenu
Copy link
Member

@crisbeto crisbeto left a comment

Choose a reason for hiding this comment

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

LGTM, the two CI failures will be resolved by #6956.

@crisbeto crisbeto added pr: lgtm action: merge The PR is ready for merge by the caretaker labels Sep 10, 2017
Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

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

LGTM

@mmalerba mmalerba merged commit 1cccd4b into angular:master Sep 12, 2017
mmalerba added a commit that referenced this pull request Sep 13, 2017
mmalerba added a commit that referenced this pull request Sep 13, 2017
* Revert "feat(datepicker): Add Moment.js adapter (#6860)"

This reverts commit 9545427.

* Revert "fix(menu): multiple close events for a single close (#6961)"

This reverts commit 1cccd4b.
mmalerba added a commit that referenced this pull request Sep 13, 2017
mmalerba added a commit that referenced this pull request Sep 13, 2017
* Revert "Revert "fix(menu): multiple close events for a single close" (#7036)"

This reverts commit dcfe515.

* Revert "feat(datepicker): Add Moment.js adapter (#6860)"

This reverts commit 9545427.

* Revert "fix(menu): multiple close events for a single close (#6961)"

This reverts commit 1cccd4b.

* Revert "fix(menu): nested trigger staying highlighted after click (#6853)"

This reverts commit 04bf3d1.

* Revert "feat(viewport-ruler): add common window resize handler (#6680)"

This reverts commit 881630f.
josephperrott pushed a commit to josephperrott/components that referenced this pull request Sep 15, 2017
* fix(menu): multiple close events for a single close

Don't emit a closed event when another event will be emitted. Previously, if one clicked on a menu item, one would get two events: `undefined` and `click` in that order. One would see similar behavior for `keydown` or clicking the backdrop. Unit tests were updated to prevent a regression.

* Responding to review comments from @crisbeto

* Observable.empty() -> Observable.of()
_closeMenu -> _destroyMenu
josephperrott pushed a commit to josephperrott/components that referenced this pull request Sep 15, 2017
…#7036)

* Revert "feat(datepicker): Add Moment.js adapter (angular#6860)"

This reverts commit 9545427.

* Revert "fix(menu): multiple close events for a single close (angular#6961)"

This reverts commit 1cccd4b.
josephperrott pushed a commit to josephperrott/components that referenced this pull request Sep 15, 2017
…lar#7054)

* Revert "Revert "fix(menu): multiple close events for a single close" (angular#7036)"

This reverts commit dcfe515.

* Revert "feat(datepicker): Add Moment.js adapter (angular#6860)"

This reverts commit 9545427.

* Revert "fix(menu): multiple close events for a single close (angular#6961)"

This reverts commit 1cccd4b.

* Revert "fix(menu): nested trigger staying highlighted after click (angular#6853)"

This reverts commit 04bf3d1.

* Revert "feat(viewport-ruler): add common window resize handler (angular#6680)"

This reverts commit 881630f.
@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