-
-
Notifications
You must be signed in to change notification settings - Fork 27
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
Property update notifications happen for all state changes, not only the relevant plucked
properties
#68
Comments
The choice whether you'd like to get notified depends on the actual subscription and how often it fires. In RxJS you would solve this using the @connectTo({
selector: {
list1: store => store.state.pipe(pluck('list1'), distinctUntilChanged()),
list2: store => store.state.pipe(pluck('list2'), distinctUntilChanged())
}
}) There are tons of other crazy operators you can use to mix and match. So it's really up to the consumer (subscription) to decide what he wants as the only sane default is, fire always ;) |
Thanks for the quick response, this is a good workaround In the documentation, it mentions The per selector here is a bit misleading. It also doesn't make much sense to have two separate methods for change handling if they are going to be triggered by every change any way. I think the more obvious behavior would be to default to this one and then have a potential override for the previous behavior |
Another thing that is different from the normal observables is that whenever the change-handler is triggered, the property itself hasn't been updated yet, whereas with a normal observable when you get the change notification, the property will already be set correctly |
I do understand your concerns, still there is a reason why there's the distinctUntilChanged operator and it is not used as default for subscriptions. I wouldn't really see a different way of solving that properly without applying the operator automatically and that does feel too much like black magic for me. Coming from RxJS in other projects it certainly wouldn't feel right to have operators automatically applied to your own subscriptions. Would you feel like clarifying the docs, and adding the hint for distinctUntilChanged, could be enough here? If so a PR would be welcome to make it easier for you to frame it in your words. With regards to the changed-handler behavior, this is documented at the end of this section |
OK, that sounds reasonable, I will have a look at the documentation to see if I can provide an update. In terms of changing the API, maybe it's an idea to implement something like this:
such that you can do the following:
This would abstract the RxJS behavior away, which I think is the main goal of this project. |
great, feel free to modify parts of the docs that do not sound reasonable, we can work on the details in your PR if somethings unclear. With regards to your helper function. This is indeed a practical way to even further reduce a bit of boilerplate. Providing that out of the box from the framework though feels a bit limiting. The trouble with the implementation of your What would you think of a companion package that could include helpers like these? There are for sure tons of opportunities which make sense in specific cases and just don't suite for sensible defaults nevertheless would provide help for other users. So e.g also various middlewares that might be of use. The idea of the store plugin is to keep the essential parts with generic defaults so it does not limit the user. Accompanying packages could fill the gap of providing more specific solutions. |
Yeah, that could be a potential solution. I think my main gripe with this behavior is that strays from the way Aurelia normally works.
This is more about complying with expectations and thus making the transition smoother. I could come up with a helper package to do 1, do you have any pointers on how you would go about accomplishing 2? |
I do get your point. State handling, and specifically in mix with RxJS, doesn't suite that too well though. So there is a hard fight between conforming with the Aurelia way, yet not sacrificing potential for RxJS based approaches. With regards to 2, are you talking about the general changedHandler as a name or the individual change handler by selector? |
What I mean by 2 is for example this:
So, a way of delaying the handler being invoked, until the value is set. This is especially handy in circumstances like this:
|
Hmm yeah I see. All of that stemmed from the general changedHandler, which typically is used when no selector or whatever is provided. That one does not get the old state propagated but instead is fired before setting the new, so that users can poke this.state for back-comparisons. With the rewrite I guess all got changed to execute in this way. @jmzagorski what do you think about this? If we're going to do this, it's going to be a breaking change, since the order change might have dramatic effects, e.g. conditionals go wrong, for existing apps. @Kennethtruyers I think it would make sense to extract this part as an issue for itself, as this one becomes heavily mixed with various things |
Yeah, completely agree, this is really a separate issue. I will create a separate ticket for it. I also agree that it's a breaking change, so it would either need to be configurable or very well communicated. |
Ticket is here: #69 |
Great, big thanks for support. Alright so with regards to the other issue lets see how the package comes along I've already some ideas I'd like to contribute |
Hm, thinking about it now, I think this change is a bit of a hack on top of it and I think there's a cleaner way to do this. With this implementation, you'd get a redundant declaration, because you have to define the plucked properties as values to the selector and then also as properties on the class. I think a nicer way to do this would be using attributes:
I have no idea whether this possible or how to do it though. |
The docs for distinctUntilChanged say that:
If every action returns a new state object, aren't the references going to be not equal and detect a change every time? |
Not really, the root state object may have changed, but the items inside the state will still be the same:
After changing List 1:
|
I suspect so. I remember having tried something similar in the begin without success :( |
lets see if i am following:
|
@zewa666 I had a go at creating a decorator for this, but unfortunately got stuck as well. You can decorate the property and rewrite the getter/setter to it pulls from the state-object. I was unable to access the methods on the class the property belongs to though (to call the Aurelia can do it, because they pass the entire viewmodel through a configuration method and have the viewmodel in scope so they can call the handler |
I think this is maybe something to think about when heading for vNext support. Generally the Store is going to be one of the first plugins thus having the chance to actively shape the APIs. What we should start to think about is maybe how the perfect, boilerplate free code may look like. Then we can figure out whats doable and what not. I feel like property decorators are going to play a role there but lets not limit us here. Looking forward to seeing your guys suggestions. |
Just came back to this issue and to answer you question @zewa666 for my personal liking, this would be the cleanest syntax possible:
Let me know your thoughts and if I can be of help |
I'm submitting a bug report
1.1.0
Please tell us about your environment:
Operating System:
Windows 10
Node Version:
8.9.3
NPM Version:
5.8.0
JSPM OR Webpack AND Version
WebPack 3.10.0
Browser:
all
Language:
all
Current behavior:
Given the following code:
When we add an item to list1 or to list2 both
list1Changed
andlist2Changed
are calledOnly
list1Changed
should be called when an item is added tolist1
(and vice versa for list2)Gist: https://gist.run/?id=75aadba05ee34f0e9c0edc10da2d917a
Avoiding unnecessary updates and screen repaints on all state properties whenever one property changes
The text was updated successfully, but these errors were encountered: