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

feat: add a common class to be used when dealing with selection logic #2562

Merged
merged 7 commits into from
Jan 13, 2017

Conversation

crisbeto
Copy link
Member

@crisbeto crisbeto commented Jan 7, 2017

Adds the MdSelectionModel class that can be used when dealing with single and multiple selection within a component.

Relates to #2412.

Adds the `MdSelectionModel` class that can be used when dealing with single and multiple selection within a component.

Relates to angular#2412.
@crisbeto crisbeto requested a review from jelbourn January 7, 2017 19:26
@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Jan 7, 2017
* Class to be used to power selecting one or more options from a list.
* @docs-private
*/
export class MdSelectionModel {
Copy link
Member

Choose a reason for hiding this comment

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

Let's omit the Md prefix, since this will be part of the cdk. I'd also be okay with just calling the class Selection (with corresponding SelectionChange) (I do want to avoid prefixing any cdk classes with Cdk)

* Class to be used to power selecting one or more options from a list.
* @docs-private
*/
export class MdSelectionModel {
Copy link
Member

Choose a reason for hiding this comment

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

We should be able to make the class generic:

export class SelectionModel<T> { ... }

And then any properties dealing with the item are of type T (or arrays as T[])

private _unflushedDeselectedValues: any[] = [];

/** Keeps track of the selected option that haven't been emitted by the change event. */
private _unflushedSelectedValues: any[] = [];
Copy link
Member

Choose a reason for hiding this comment

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

Move all of these properties above the constructor

private _selectedValues: any[] = [];

/** Keeps track of the deselected options that haven't been emitted by the change event. */
private _unflushedDeselectedValues: any[] = [];
Copy link
Member

Choose a reason for hiding this comment

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

Not sure "unflushed" is the right term here. How about something like "pendingDeselection", "deselectedToEmit"?

onChange: Subject<MdSelectionChange> = new Subject();

/** Currently-selected values. */
private _selectedValues: any[] = [];
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 keeping an array of selectedValues, we should keep the selection in a Set (named _selection). We can use .keys() when we want the list of selected values (caching the value). This will make selecting, deselecting, and checking selection much faster (and the code simpler). When the options are updated, the update would then look like.

Overall this would change insertion, deletion from O(k) to O(1) and keep getting an array of the selected values mostly the same.

*/
export class MdSelectionModel {
constructor(
private _options: any[],
Copy link
Member

Choose a reason for hiding this comment

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

I think we can avoid keeping _options in this model completely if we add it as an argument to selectAll. That would make this class much simpler (no update logic, remove _verifyExistence)

@crisbeto
Copy link
Member Author

Re-did it based on the feedback @jelbourn.

/**
* Selects a value or an array of values.
*/
select(value: T): void {
Copy link
Member

Choose a reason for hiding this comment

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

I think it's a bit confusing to have select and _select methods that do different things. Maybe make the private one something like _markSelected? (same for deselect and clear)

Copy link
Member Author

@crisbeto crisbeto Jan 11, 2017

Choose a reason for hiding this comment

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

I'd say it's probably better to move the clearing of the selected value to _select instead. That way the only difference is whether the event is emitted.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

Copy link
Member

Choose a reason for hiding this comment

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

I still think, though, that having a select and _select method is something we should avoid. It would be very easy to call the wrong one.

Copy link
Member Author

@crisbeto crisbeto Jan 11, 2017

Choose a reason for hiding this comment

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

_markSelected makes sense, but should I rename _deselect and _clear in that case as well?

Copy link
Member Author

@crisbeto crisbeto Jan 11, 2017

Choose a reason for hiding this comment

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

Changed up the names so they're not easily confused with the public ones.

@jelbourn
Copy link
Member

LGTM

@jelbourn jelbourn added pr: lgtm action: merge The PR is ready for merge by the caretaker and removed pr: needs review labels Jan 11, 2017
@tinayuangao tinayuangao merged commit c295fa9 into angular:master Jan 13, 2017
@jelbourn jelbourn mentioned this pull request Jan 27, 2017
1 task
@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 6, 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.

4 participants