MarimerLLC / cslaforum

Discussion forum for CSLA .NET
https://cslanet.com
Other
31 stars 6 forks source link

Is it possible to use LazyGetProperty on child objects when using Blazor client? #855

Open drakeforte5 opened 4 years ago

drakeforte5 commented 4 years ago

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?

`
public static readonly PropertyInfo AccountCategoriesProperty = RegisterProperty(c => c.AccountCategories);

public AccountCategories AccountCategories { get { return LazyGetProperty(AccountCategoriesProperty, () => DataPortal.Fetch()); } private set { LoadProperty(AccountCategoriesProperty, value); } }`

Thank you.

rockfordlhotka commented 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.

drakeforte5 commented 4 years ago

Ah, new features! I still have the 5.0.1. Is this available in the 5.1.0-R19110701 prerelease in nuget?

Thanks.

rockfordlhotka commented 4 years ago

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.

drakeforte5 commented 4 years ago

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.

rockfordlhotka commented 4 years ago

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));
  }
rockfordlhotka commented 4 years ago

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.