Open drakeforte5 opened 4 years ago
I haven't tried lazy loading in Blazor yet, so I don't know for sure. However, I have discovered that async operations often "fool" the Blazor data binding automatic change detection.
As a result, at the moment anyway, I've been doing this as my page initializes:
protected override void OnInitialized()
{
vm.ModelChanging += (o, n) =>
{
if (o != null)
o.PropertyChanged -= async (s, e) => await InvokeAsync(() => StateHasChanged());
if (n != null)
n.PropertyChanged += async (s, e) => await InvokeAsync(() => StateHasChanged());
};
}
Basically hooking the model's PropertyChanged
event to force a StateHasChanged
call.
I'm sure this triggers some unnecessary rendering. However it also ensures that background async operations (like lazy loading??) always affect the UI.
Ah, new features! I still have the 5.0.1. Is this available in the 5.1.0-R19110701 prerelease in nuget?
Thanks.
So close!! I'm altering/enhancing the code as I'm writing the CSLA-Blazor book, so things have been changing day-to-day.
I think I'm almost done though - things are looking pretty nice imo.
Looking forward for the update! I suppose I really have to use the ViewModel instead of the static factories if I wanted the StateHasChanged/PropertyChanged to bubble-up from the BO to the UI.
Pretty excited about this Blazor stuff, reminds me of silverlight. One thing I notice is that it is better to use the client/webassembly project template right of the bat than the server project template - it just forces you to do things correctly whereas the server-side template makes you do shortcuts and I suppose lazy because of the convenience of not having to think about the separation of the client and the server interactions.
I'm building all my support around the ViewModel
class, yes.
But you can still use static factories if you want - you just can't use the RefreshAsync
method that's provided by the ViewModel
class.
This is a good topic I need to remember to cover in Chapter 7 😄
To use a static factory, instead of this
protected override async Task OnParametersSetAsync()
{
if (string.IsNullOrWhiteSpace(id))
await vm.RefreshAsync();
else
await vm.RefreshAsync(int.Parse(id));
}
You'd do something like this
protected override async Task OnParametersSetAsync()
{
if (string.IsNullOrWhiteSpace(id))
vm.Model = await ProjectEdit.NewProjectAsync();
else
vm.Model = await ProjectEdit.GetProjectAsync(int.Parse(id));
}
Regarding the client template, I agree. Though I just finished Chapter 6, which focuses on how to build what's called a multi-headed solution where your Blazor UI is in a class library that is referenced (and hosted) by a client-side and a server-side Blazor project. This makes it easy for you to switch between SSB and CSB to run the same code.
The immediate (and substantial) value is that server-side debugging is far more powerful, so it is nicer to work in that setting as a dev, but you probably want to deploy to WebAssembly, and this technique means you are always building for both - hard to make mistakes.
I have a hierarchical data and wanted CSLA to handle the lazy loading of the child collection using the LazyGetProperty. It seems this option does not work when used in a Blazor (client) project. I did not test the server style Blazor.
How will the binding on the client side be notified of the loaded child objects? StateHasChanged() is the way Blazor renders changes but how can this be hooked with the LazyGetProperty?
` AccountCategoriesProperty = RegisterProperty(c => c.AccountCategories);
public static readonly PropertyInfo
public AccountCategories AccountCategories { get { return LazyGetProperty(AccountCategoriesProperty, () => DataPortal.Fetch()); }
private set { LoadProperty(AccountCategoriesProperty, value); }
}`
Thank you.