[Enhancement] Bind to .NET 5 Records and update automatically when replaced #319
Replies: 6 comments
-
Maybe i didn't understand what you mean but data records are supposed to be used when all property of a class are immutable. So how you UI can change track of change on object that can't be changed... It sure get rid of INotifyPropertyChanged. The "With" doesn't update it create a copy of the object if every time you want to update you make a copy it will be very slow. |
Beta Was this translation helpful? Give feedback.
-
@GeraudFabien That's exactly the point. Most other tools use the concept of immutable state and cause the state to be updated all at once, then a diff is done with the changes (which the record function knows) and then draws. This gets rid of all of the multi-threaded nightmares that IPropertyNotifyChanged causes because all changes happen at once with the record. If you're view model itself is a record then the Update need only happen on the setter of the binding with a diff from the last time. Especially if everything was strongly typed from the beginning so the shape of the view model is known from the start and not just an object. Now if with on records somehow passed all of the changes on at once in a notification, this would be even better because the diff would already be done and you wouldn't have to walk the stack. |
Beta Was this translation helpful? Give feedback.
-
@GeraudFabien I updated my initial request and gave it my best language designer approach to how I'd suggest this works. The best way would require the .net core team implementing the functionality, but if done right would solve state management completely and make Xamarin and the rest the very easiest to work with UX as a result, and cause UX updates to be vastly faster than how everyone else is doing it. Incidentally this would also make Forms much easier as a standard record of say "FormObject" could be created that would convert to and from T automatically for the data being stored and could keep track of pure, clean, dirty, reset, errors etc. and all of the binding stuff would just work. A little syntactic sugar on all input controls would allow you to set it once for the control to the FormObject for 2 way binding and voila, you have forms with almost 0 additional code especially if you public model allowed a generic type that was the DTO that it was being created from that automatically instantiated all of the properties from the DTO in a optional constructor thus eliminating all of the boilerplate of taking your data from your API and getting it into your state and into your forms. (which is about 90% of the work eliminated along with all of the bugs that go along with that) |
Beta Was this translation helpful? Give feedback.
-
how about something like this...
So need for making a compare on all record properties... |
Beta Was this translation helpful? Give feedback.
-
@groege It would be more consistent with other languages if you're going to do that to use: setState(() => { ... }); But if you're using records you can bulk change in a single operation the entire state so it makes all of that irrelevant and can strongly type the model. |
Beta Was this translation helpful? Give feedback.
-
Binding and State management is a lot easier on Blazor, I hope they move to something closer to that model. Binding on Xamarin was like 5 to 30 lines of code per property bound because it didn't use component lifecycle events or state change calls. It was remarkably annoying and extremely verbose. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
.NET 5 provides the ultimate state management and binding capabilities with data records. Because you can change multiple properties and it does value comparison it should be both fast and ultra-reliable. It would be VERY nice to be able to bind to records and be able to update them with the "with" syntax by reassigning the binding property to the new version and have the render tree automatically update based on changes.
To me this is the way forward for how databinding should work instead of using IPropertyChangeNotify.
API Changes
Don't know. Probably a lot. Would be nice if we could use Generics on the base page/content etc. as well so that we could strongly type the Bound object and reference it using the generics strongly instead of objects as part of this work.
Intended Use Case
This would make binding much easier, much less error prone and should speed up just about the entire pipeline because binding changes would simply and always be with {<properties changing}
Example:
Note the "with" syntax on the property. This would be added by the core .NET team. BindingContext would have it's definition changed to something like: public observable T BindingContext {get; set;} or something smiliar. Once the observable keyword was used, then 3 things would occur:
You could subscribe to it and get an event in one shot that contains if it was fully replaced or set, or just patched as the ChangeType on eventargs. And if patched, it would include the patch (the "with").
It would create a generator in Xamarin Forms (or any other ui toolkit) that would automatically walk to graph of the record's motifications and cause a redraw of anything that is bound to the things that changed in the patch (or the entire object) thus eliminating reflection.
Every thing that binds would assign the binding automatically to the property so that the entire graph was strongly linked and every dependency was known as part of "observable".
And of course it would have the ability to isolate what's bound so that you can create components/views that are assigned to sub-properties of the page's record and thus as soon as it's assigned, the entire update graph is already fully and strongly linked thus making updates to the UI incredibly fast, strongly typed, and fully under the control of the developer allowing really great batch update characteristics.
This would also need the use of ImmutableArray/ImmutableList/ImmuntableDictionary throughout the record instead of other types so that changes to collections would be easily trackable as well. This might make the case for public model instead of public record and have it enforce this limitation. Obviously either way, a property could be observable or not and if not observable, while still bindable on iniital load, wouldn't cause change tracking or updates. Of course if a property had "observable" then the property would be implicitly init; only and both not require it, and not allow anything else.
Youl could also create observable functions (knockoutstyle computed) that list the properties that affect it:
publc observable Task SomeCalculatedProperty(params) with [Greeting, someother observable] => NotImplementedException() that would also cause the graph to be updated for anything that bound to it if any of the with [observable properties array] causing a recalc and change.
This bit of syntactic sugar and automation would make Xamarin/WinUI/Uno/Etc. have by far the best state management of any language and would make it incredibly clear and obvious what's going on and prevent all of the nasty async issues with IPropertyNotifyChanged etc.
For Providers of state outside the current object, that's easy. You would just use DI to inject any observable object into the page/view/state record and set a property in the constructor that was observable. Then anything that binds on the page to that observable property would automatically get full binding capabilities.
Of course 2 way binding would just automatically do a with { property = newvalue} for you.
Beta Was this translation helpful? Give feedback.
All reactions