-
Notifications
You must be signed in to change notification settings - Fork 401
Conversation
f4a1836
to
94215a3
Compare
👍 This is a major problem for me, deep watchers are too greedy and we have BIG models in API that we consume. From my perspective small watchers on needed fields are much better than one big deep watch. |
94215a3
to
7c76daa
Compare
Current coverage is
|
const stringWatchers = {} | ||
|
||
angular.forEach($scope.fields, function(field, index) { | ||
if (field.data && Array.isArray(field.data.watch)) { |
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.
If it's part of the core API of angular-formly, then it shouldn't go in data
, but it could go in extras
.
This looks pretty good. Please just use |
P.S. Let me know when you update the PR (github wont notify me). |
1f24080
to
1c7bc62
Compare
/me pokes @kentcdodds |
I'm just not sure about my 'watcher grouping' magic. It seems to be working fine but I was wondering if it was so easy to implement why angular team didn't implement it globally in the core... |
1c7bc62
to
6551b1d
Compare
Thanks for doing this. The tests are great. I wonder if it might be easier if |
@kentcdodds it seems like a valid case, I have updated the PR to incorporate your suggestion |
With that, do we really need the extras watcher? We already have a mechanism for adding a watcher to a field... I'd rather avoid adding another way to do the same thing. |
@kentcdodds we don't, that's why I wanted to be able to add watchers through Scenarios:
|
Right. What I'm saying is for that second bullet point, you can use the |
@kentcdodds ok this is a gamechanger... why did I even work on this if this was already available 👻 |
@kentcdodds OH WAIT! You have to manually define listener for each of these expressions in your implementation of These two seem to be similar but in fact do 2 different things. |
Sorry. I guess I didn't understand your problem well enough. I still think that it would be valuable to be able to disable the deep watch and provide a custom watch function for the whole form. |
Ah, indeed... Hmmm.... I wonder if there's a way we could enhance the existing API to account for the use case |
@kentcdodds well, I might try but it will be more complicated. I however agree that adding Btw your api is broken for a field with custom model and string expression in watcher. |
We could consider doing 2 things:
This would mean that instead of:
we would have:
That said, this can be done but it may seem a bit confusing. It could be less confusing if
HOWEVER this still doesn't look right. For me, this @kentcdodds what do you think? I'm torn apart :) One way or the other, I'd like this feature pushed as soon as possible because it gives enormous boost to me app at work. |
That's probably a little bit too magical I think. Maybe if we added another property to |
@kentcdodds that sounds fine, I will let you know when I'm ready |
5c125fc
to
61dfd04
Compare
Ok @kentcdodds, I think I did it. However I went a little overboard so we might consider reverting one functionality but more on it later. Basically I did:
I have written some tests and smoke tested these features on my work project and it works fine. |
8c0bb8b
to
4b5fca3
Compare
Haven't looked at the code yet, but I can tell you right now that there's a reason that So, if you could removed that piece, then I'll give the code a look. Let me know if you have any questions. Thanks a ton! |
@kentcdodds I know about that reason (however this is valid only when you example:
This is how it works in the current latest formly release:
This is how it works with my PR (notice
|
If you wanted to fix the |
@kentcdodds the problem is that this object is used to evaluate the
It will evaluate the model the wrong way in
it all works fine but it seems a little bit hacky to me... it would take Anyway, I will revert the fix for |
eb3f020
to
10905d6
Compare
$scope.$watch(() => field.model, onModelOrFormStateChange, true) | ||
watchedModels.push(field.model) | ||
} | ||
}) | ||
} | ||
|
||
function setupExpressionWatchers(field, index) { |
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.
This only sets up a watcher for hideExpression
. Perhaps the function should be called setupHideExpressionWatcher
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, I have refactored the name
This is excellent @kwypchlo. Thank you. If you could address my one comment, I give this a 👍. I would like someone from @formly-js/angular-formly-collaborators and another person from @formly-js/angular-formly-collaborators-read to also review this PR and give a 👍 or 👎 |
- add manualModelWatcher option that accepts boolean or custom watcher function for more flexibilty - add watchAllExpressions option (boolean) that puts angular watcher on every field expression - add runFieldExpressions option to custom field watcher that runs field expressions on expression change
10905d6
to
8167abd
Compare
@kentcdodds cool! When this is accepted I could prepare the fix for the |
@kwypchlo Great job! |
Thanks @kamilkisiela! I'll go ahead and merge this in then. |
adds manualModelWatcher option
This will be auto-released in a few minutes. Thanks a bunch @kwypchlo! |
Cool! :) |
This is a proposal draft of a functionality that speeds up forms with very complex models. It works on my application at work :)
Problem: I have model that is extremely large (over 500KB) and multiple forms that I need this model to be passed to (over 10). There is a deep watcher created for every formly-form instance (so it's over 10) that watches the same model on every digest cycle.
So I did some digging:
This deep watcher is created in the FormlyFormController and is needed to fire formly expressions (hide, validations and custom expressions). I know exactly what fields from the model can trigger these expressions to be changed but formly is watching the whole model anyway, even if I don't have any expression or validation.
Solution:
I added an option to manually define parts of model that should be watched instead of watching the whole model. This is done by passing
manualModelWatcher
option to formly-form. If you do that, formly will not set watch on whole model but will iteratedata.watch
array on every field (if there is one) and set multiple small watches.Example usecase:
I have model that is over 500KB and all I need in my form is to watch for
model.type
change and show/hide couple of fields depending on that type. in my case, I would just dodata: {watch: ['model.type']}
on every field that defines thehideExpression
and it works, yay! Instead of making a whole model deep watch, I've manually set to just watch what I need.Tell me what you guys think. If this implementation is cool I will add docs to that :)