2

What is a good way to reuse blazor component multiple times (100+)?

Let's say I have a list of 100+ coins that I loop throw.

Home page:

@page "/Index"

// html code

@foreach(var c in coins)
{
   coin = c;
   <CascadingValue Value="@coin">
      <ProjectName.Pages.CoinComponent />
   </CascadingValue>
}

// html code

@code {

   // List of 100+ coins
   [CascadingParameter] List<Coin> coins { get; set; }

   // Coin object
   Public Coin coin { get; set; }

   // C# code
}

Coin Object:

public class Coin
   {
       public Guid Id { get; set; }

       public int Size { get; set; }

       public int Value { get; set; }

       public string Color { get; set; }

       // ect
    }

Coin page:

@page "/CoinComponent"

// html code

<div class="CoinCssClass @coin.Size @coin.Color">
   <div class="CoinCssClassValue">@coin.Value</div>
</div>

// html code

@code {
   [CascadingParameter] Coins { get; set; }

   //C# code
}

This kind of works but is there a better way of doing this?

Justin
  • 103
  • 1
  • 10
  • What do you consider "better way" ? – Vencovsky May 13 '20 at 16:04
  • My example works if the objects involved are small and few. Maybe I should have asked how can my example be scaled up, is there a offical recomondation for reusing components or just how to reuse blazor components. I know "better way" isn't saying much and is pretty personal. – Justin May 13 '20 at 18:53
  • I think you have a typo in the `CoinComponent` part, near `CascadingParameter` (what is the type of `Coins`? And shouldn't it be simply `coin`?). – Mu-Tsun Tsai May 14 '20 at 02:13
  • Yes, the typo is luckily only in this example and not in my equal code – Justin May 14 '20 at 07:59

2 Answers2

4

I think what you're looking for is something like the following:

Home page
@page "/Index"

@foreach(var c in coins)
{
   <ProjectName.Pages.CoinComponent coin="@c" />
}

@code {
   // I'm not sure where did these coins cascade from...
   // Did you actually cascade them from the layout or above?
   // Well, you shouldn't.
   [CascadingParameter] List<Coin> coins { get; set; }
}
CoinComponent
// You don't need @page since this is not intended to be a standalone page.

<div class="CoinCssClass @coin.Size @coin.Color">
   <div class="CoinCssClassValue">@coin.Value</div>
</div>

@code {
   // use Parameter instead of CascadingParameter
   [Parameter] Coin coin { get; set; }
}

Mu-Tsun Tsai
  • 2,348
  • 1
  • 12
  • 25
0

Answer from : https://mikaelkoskinen.net/post/render-razor-component-instance-blazor

Using the code below you render any component again without reintializing it again. But you have to keep track of the instances. Tested working in .NET 8

Welcome to your new app.
 
@RenderContent(counterInstance)
 
@functions{
    Counter counterInstance = new Counter();
 
    RenderFragment RenderContent(ComponentBase instance)
    {
        var fragmentField = GetPrivateField(instance.GetType(), "_renderFragment");
 
        var value = (RenderFragment)fragmentField.GetValue(instance);
 
        return value;
    }
 
    //https://stackoverflow.com/a/48551735/66988
    private static FieldInfo GetPrivateField(Type t, String name)
    {
        const BindingFlags bf = BindingFlags.Instance |
                                BindingFlags.NonPublic |
                                BindingFlags.DeclaredOnly;
 
        FieldInfo fi;
        while ((fi = t.GetField(name, bf)) == null && (t = t.BaseType) != null) ;
 
        return fi;
    }
user160357
  • 865
  • 10
  • 14