-
Notifications
You must be signed in to change notification settings - Fork 25
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 template base signals and equality check #2484
Conversation
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.
Nice to have for sure. The timer component code is a bit confusing to me but I'm not keen to refactor it now – everything seems to be working as expected from a functional perspective. I also added a minor code tidy in a63fdb1 to clean up a line that was throwing a typescript warning/error.
See my inline suggestion for the equality checker.
// handle deep comparison for arrays | ||
if (Array.isArray(a)) { | ||
const differentEl = a.find((v, i) => !isEqual(v, b[i])); | ||
return differentEl ? false : true; |
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.
nit(blocking): This will throw a false positive if a differentEl
is found that is falsey (e.g. if a
contains a 0
element at an index that b
has a different element, e.g. a = [0]
and b = [1]
).
How about this instead:
if (Array.isArray(a)) {
if (a.length !== b.length) return false;
return a.every((v, i) => isEqual(v, b[i]));
}
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.
Really nice catch, you're right isEqual([true],[false])
would a true
value.
I tend to not like every
operators as there's really no reason to continue processing once you've found an element that differs (can add on a bit of time if dealing with very large arrays). Instead I've added 3a16bc9 which uses the findIndex
operator to instead focus on the index of the element that differs and ignoring the specific value. I've also updated the spec test to catch this example
Update code and spec to handle case where arrays differ but the different value is falsy (and the `find` operator returns as such). Instead prefer to use `findIndex` to ignore the value and just look for index of mismatch
// find the first element index where there is a mismatch | ||
// if all elements are the same `findIndex` returns value -1 | ||
const differentIndex = a.findIndex((v, i) => !isEqual(v, b[i])); | ||
return differentIndex === -1; |
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.
Nice, this seems like a good way to do it. However, we still need a check that the arrays are of equal length first, otherwise it will return a false positive if b
contains the same elements as a
plus some additional elements. E.g. isEqual([1],[1,2])
will return true
currently
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.
another good case, thanks for pointing out.
Added length check and updated test with 261a7d9
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.
Also realised that will need to explicitly check b
is an array as relying on previous typeof
check could match object
type for both []
or {}
(or even dates or null
objects)
Updated with b43d534
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.
Looking good, just a merge conflict to resolve now...
…pp-builder into feat/template-signals
PR Checklist
Description
Add signals to template base component for more fine-grained updates to row value, parameter_list and action_list updates
This will allow components to refer directly to
value()
property (instead of_row.value
) and also apply computed effectsReview Notes
It isn't expected for this to have much impact as the properties are newly added. The only issues are with any components that provide their own definition for
value
,parameterList
oractionList
(instead of accessing via_row.value
)Looking at the tests there were a few components that did have conflicts and have been updated accordingly (would be good to confirm timer working as expected as that was slightly less trivial to update).
Dev Notes
This is a bit of a forward-looking update to provide devs the option of directly linking to row value or parameter list updates using signals. These should be more performant and reliable than responding to
_row
changes more generally.The changes also include a custom equality checker, as the default for angular signals is the
Object.is
function which only matches equality for strict object equivalence e.g. same array but not two arrays with same entries so thathttps://angular.dev/guide/signals#signal-equality-functions
I have only included the parameterList, actionList and value properties for now as I think these are the main columns likely to be updated dynamically (e.g. containing dynamic refs). Note that the
condition
column will always be interpreted outside of the template component itself (and not render the component if false), andhidden
column dealt with at the container level.I had wanted to also include a more general
row()
signal (if wanting to trigger changes generally when full row updates), however this would conflict with the existing row setter functions.In the future it might be good to start refactoring some components to use the signals (particularly ones that use
@Input() set row
bindings), however this should be done on a case-by-case basis to check for any side-effects.Git Issues
Closes #
Screenshots/Videos
If useful, provide screenshot or capture to highlight main changes