-
Notifications
You must be signed in to change notification settings - Fork 423
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 extra caller property to onSelectedRowsChanged #659
Conversation
- this is to cover a special use case that we have, in which the user can click a row which will possibly trigger other rows to be selected (Tree Data grid), so we basically dynamically change row selection following certain logic (via `setSelectedRows`) and the current code was problematic because SlickRowSelectionModel is also calling `setSelectedRows` and we had no way of knowing if the selection was made by the user or dynamically by the code, this PR adds a `caller` property which tells us who called the row selection. - also added extra properties, 3x in total: (`caller`, `changedSelectedRows` and `changedUnselectedRows`), this makes my code a lot cleaner since I often have to add extra code to know the last changes
// provide extra "caller" argument through SlickEventData to avoid breaking pubsub event that only accepts an array of selected range | ||
var eventData = new Slick.EventData(); | ||
Object.defineProperty(eventData, 'detail', { writable: true, configurable: true, value: { caller: caller || "SlickCellSelectionModel.setSelectedRanges" } }); | ||
_self.onSelectedRangesChanged.notify(_ranges, eventData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@6pac could you review and provide feedback to this PR please.
I had to resolve to cheating code to get this working, I'm passing extra data via a SlickEventData (which was not made for that), but I don't see any other ways to pass extra data since onSelectedRowsChanged
and onSelectedRangesChanged
only resolve arrays of SlickRange and/or row number. We typically return an object that we can extend in the future but these events only have arrays which we can't really extend and so no ways of providing extra stuff which is why I resolved to using cheat code. Are you ok with the change? Do you have any other suggestions that might work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I can see, the calling pattern for onSelectedRowsChanged
in the core grid is:
if (simpleArrayEquals(previousSelectedRows, selectedRows)) {
trigger(
self.onSelectedRowsChanged,
{ rows: getSelectedRows(),
previousSelectedRows: previousSelectedRows
},
e);
}
So this uses the 'args-is-an-object' convention, and you should be able to just add the property.
For onSelectedRangesChanged
, it appears only to be used in cellselectionmodel and rowselectionmodel (though it may also be called by user code), with the call:
_self.onSelectedRangesChanged.notify(_ranges);
This doesn't follow the convention of 'args-is-an-object', which really should be corrected, but that would be a breaking change. The only non-breaking way I can think of is to take advantage of the fact that in js an array is also an object. So we could do, for example:
var args = _ranges;
args.ranges = _ranges;
args.caller = caller;
_self.onSelectedRangesChanged.notify(args);
a bit of a hack, but technically correct. It may be confusing when looking in the debugger, but I think a comment at the call would be enough to demystify that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm I can give a try next week but I'm not crazy about this approach and I don't think that would work because the other side is really expecting an array not an object, but since nearly everything is an object in JS we never know, I'll give a try next week. If that doesn't work, my approach, even if not ideal, is still working and for the most part this code is used only internally (to communicate between SlickGrid & the plugins) so we might be ok since it's not that expose to the outside user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. What I'm suggesting is that in internal code we treat it as an object. Setting it as an array is only to maintain backwards compatibilty for legacy user calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that my proposed solution is a hack, I think yours works equally well, so either-or. The issue with onSelectedRangesChanged
does need to go on the list for when we finally release a breaking version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@6pac yeah I would rather merge it as it is, I know it works with use case in our Salesforce environment and so I would rather use that for now. It's mostly an internal thing but you never know when someone hooks into any of the onSelectedRangesChanged
events (I'm sure there's someone in the world doing that) so I would rather not break them and my solution even though hacky as well isn't too bad and it works without breaking anything
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, so we are ready to merge this and release?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wait give me another 5min, I'm giving a try with your hack which is basically this SO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems to work too, but I'm not sure how that would work with TypeScript. I would say let's merge with the code I have now (it works with TypeScript in my lib) and we can keep it as a 2nd option. Let me merge my PR then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I don't think Typescript would like it. As they say in the SO post, it's not that it won't work, it's just quite an unusual pattern and might be quite confusing for some developers. OK, willl pull and release.
@6pac I merged the PR, you can go ahead with a release at your convenience |
setSelectedRows
and the current code was problematic because internally SlickRowSelectionModel is also callingsetSelectedRows
and we have no way of knowing if the selection was made by the user or dynamically by the code, so this PR adds acaller
property which tells us who really called the row selection.caller
,changedSelectedRows
andchangedUnselectedRows
), this makes my code a lot cleaner since I often have to add extra code to know the last changesNow the
onSelectedRowsChanged
provide extra properties, thecaller
property is really helpful in my use case