Fermer

mars 10, 2022

Comment rendre dynamiquement les composants Blazor


Vous ne saurez pas toujours quels composants vous devez rendre à l'avance. Voici comment rendre dynamiquement les composants en réponse à l'évolution des données.

La plupart du temps, vous savez de quels composants vous avez besoin pour votre application au « moment de la conception ».

Lorsque vous écrivez le code et le balisage de votre site, vous savez que vous avez besoin d'une NavBar, vous créez donc un composant NavBar et le restituez sur la page.

div>
    Barre de navigation />
</div>

Cela permet de regarder très facilement votre code et de voir quels composants seront rendus lorsque vous l'exécuterez dans le navigateur.

Cependant, il arrive parfois que vous ne sachiez pas nécessairement quels composants vous devez afficher sur la page.

Prenons par exemple un tableau de bord personnalisable. Vous connaissez le tri : une page qui rassemble de nombreuses informations différentes comme des graphiques, des tableaux, peut-être un formulaire ou deux.

Le mot clé ici est "personnalisable". Si vous créez simplement un tableau de bord fixe qui a le même aspect pour tout le monde, vous pouvez vous en tenir à l'approche codée en dur que nous avons mentionnée précédemment.

Mais si les utilisateurs doivent personnaliser leurs propres tableaux de bord, vous aurez probablement besoin d'une approche différente.

Tableaux de bord dynamiques

L'exigence est de prendre des composants arbitraires et de les afficher sur la page.

Dans ce cas, nous pouvons imaginer que nous pourrions stocker la configuration du tableau de bord personnalisé d'un utilisateur en utilisant une structure comme celle-ci :

DashboardConfig.cs

Publique classer Configuration du tableau de bord {
    PubliqueListerPanneau>Panneaux{ avoir; ensemble; }
}

Publique classer Panneau {
    Publique chaîne de caractèresTitre{ avoir;ensemble; }
}

Nous pouvons ensuite parcourir la liste des panneaux dans un composant Blazor.

Tableau de bordIndex.razor

@foreach (panneau de var dans le tableau de bord. Panneaux){div>
h1>
            @panel.Titre</h1>
div>
            ...</div>
</div>
 } @code { Tableau de bord DashboardConfig = ... ;  }

Jusqu'ici tout va bien, mais qu'en est-il des composants personnalisés que nous avons mentionnés ?

DynamicComponent à la rescousse

Blazor, à partir de .NET 6, a un très pratiqueComposant dynamiquecomposant dans ce but précis :

Composant dynamique Taper="@typeof(Compteur)"/>

Tant que nous connaissons le type de composant que nous voulons rendre,Composant dynamiquefera le reste.

Mettons à jour notreTableau de bordmodèle pour inclure un type de composant :

DashboardConfig.cs

Publique classer Configuration du tableau de bord {
    PubliqueListerPanneau>Panneaux{ avoir; ensemble; }
}

Publique classer Panneau {
    Publique chaîne de caractèresTitre{ avoir;ensemble; }
    PubliqueType Composant{ avoir;ensemble; }
}

Nous pouvons maintenant modifier notre balisage pour rendre ce composant en utilisantComposant dynamique.

Index.razor (balisage)

@foreach (panneau de var dans le tableau de bord. Panneaux) {div>
h1>
            @panel.Titre</h1>
div>
            Composant dynamique Taper="@panel.Component" />
</div>
</div>
}

Nous pouvons rapidement tester cela en créant une instance deConfiguration du tableau de borddans du code:

Index.razor (@code)

@code{Tableau de bord DashboardConfig= Nouveau Configuration du tableau de bord {Panneaux= Nouveau ListerPanneau>{ 
            Nouveau Panneau {Titre= "Contrer",Composant= Type de(Contrer) },
            Nouveau Panneau {Titre= "Temps",Composant= Type de(Récupérer les données) }
        }};

}

Juste comme ça, nous avons un tableau de bord !

À ce stade, vous souhaiterez peut-être remplacer le balisage de votre panneau de tableau de bord par un composant plus esthétique. Si vous utilisez une bibliothèque de composants commeInterface utilisateur Telerik pour Blazorcela vaut probablement la peine de prendre un moment pour trouver un composant que vous pouvez déposer pour agir comme un panneau de tableau de bord.

Si vous utilisez les modèles de projet Blazor par défaut, vous pouvez utiliser Bootstrap'scarteclasses pour arriver à quelque chose qui semble un peu mieux dans le navigateur :

@foreach (panneau de variables dans le tableau de bord. Panneaux) {div classer="carte mon-4">
h1 classer="en-tête de carte">
            @panel.Titre</h1>
div classer="corps de carte">
            div classer="texte de la carte">
            Composant dynamique Taper="@panel.Component" />
            </div>
</div>
    </div>
}

Voici à quoi cela ressemble dans le navigateur :

 Tableau de bord dynamique : instantané d'un tableau de bord avec deux panneaux.  Un panneau contient une instance du composant Blazor Counter standard, l'autre une instance du composant FetchData

Rendre le tableau de bord un peu plus résilient

C'est une bonne première étape, mais comment stockerions-nous réellement cette configuration de tableau de bord dans une base de données ?

Pour cela, nous devrons stocker leNomduTaper(car nous ne pouvons pas stocker un type directement dans la base de données).

Commençons par modifierConfiguration du tableau de bordutiliser unchaîne de caractèrespour le composant (au lieu d'unTaper).

DashboardConfig.cs

Publique classer Configuration du tableau de bord {
    PubliqueListerPanneau>Panneaux{ avoir; ensemble; }
}

Publique classer Panneau {
    Publique chaîne de caractèresTitre{ avoir;ensemble; }
    Publique chaîne de caractèresComposant{ avoir;ensemble; }
}

À ce stade, nous rencontrerons une erreur de compilation car nous essayons d'assigner unTaperà unchaîne de caractères lorsque nous créons nos données de test. Changeons ce code deType depournom deau lieu.

Index.razor (@code)

@code{Tableau de bord DashboardConfig= Nouveau Configuration du tableau de bord
    {Panneaux= Nouveau ListerPanneau>
        {
            Nouveau Panneau {Titre= "Contrer",Composant= nom de(Contrer)},
            Nouveau Panneau {Titre= "Temps",Composant= nom de(Récupérer les données)}
        }
    };

}

Maintenant, nous saisissons simplement le nom du composant et l'attribuons (en tant quechaîne de caractères) à la propriété du composant de notre panneau.

Mais si nous essayons de l'exécuter, nous tomberons sur une nouvelle erreur.

erreur CS1503 : Argument 1 : impossible de convertir de 'chaîne' en 'System.Type'

Le problème est que nous passons maintenant le nom du composant, maisComposant dynamiqueveut un genre.

Nous devons également gérer la possibilité que nous stockions le nom d'un composant dans le système uniquement pour découvrir, à une date ultérieure, que ledit composant a été renommé ou supprimé et ne peut plus être rendu.

Heureusement, nous pouvons résoudre les deux problèmes avec une petite modification de notre code.

D'abord, dans le@codepour notre tableau de bord, nous pouvons créer une fonction d'assistance pratique pour résoudre le type de composant à partir d'une chaîne.

Index.razor (@code)

@code{
    ...
    
    privéTaper? Résoudre le composant(chaîne de caractèresNom du composant)
    {
        retourner chaîne de caractères.EstNullOuVide(Nom du composant) ? nul
            :Taper.ObtenirType($"{App Namespace}.Widgets. {componentName}");
    }
}

Ceci suppose que les composants sont situés dans unWidgetdossier à la racine de l'application, et que nous remplacerons{App espace de noms}avec l'espace de noms réel de l'application.

Nous pouvons maintenant utiliser cette fonction dans notre balisage pour afficher le composant (uniquement lorsque nous pouvons résoudre son type).

Index.razor (balisage)

div classer="carte mon-4">
    h1 classer="en-tête de carte">
@panel.Titre</h1>
    div classer="corps de carte">
div classer="texte de la carte">
             @{ var componentType = ResolveComponent(@panel.Component);  si (typecomposant != null) {Composant dynamique Taper="componentType"/>
            } }</div>
    </div>
</div>

À partir de là, nous pouvons conserver cette configuration et la recharger lorsqu'un utilisateur tente d'accéder au tableau de bord.

Transmission de données à des composants dynamiques

Vous pouvez également souhaiter fournir une configuration supplémentaire pour un composant au-delà de son type.

Dans cet exemple de tableau de bord, vous pouvez imaginer que les utilisateurs souhaitent enregistrer des paramètres supplémentaires (comme une plage de dates ou une catégorie de produit spécifique pour un widget qui affiche les ventes).

Le défi est de pouvoir stocker une collection arbitraire de données, puis de la transmettre au composant lors du rendu.

Composant dynamiquepermet cela en acceptant un dictionnaire de paramètres de typeIDionnaire.

Mettons à jour notreDashboardConfig.Panelmodel pour stocker un dictionnaire de paramètres.

DashboardConfig.cs

Publique classer Panneau
{
    Publique chaîne de caractèresTitre{ avoir; ensemble; }
    Publique chaîne de caractèresComposant{ avoir; ensemble; }
    Publiquedictionnairechaîne de caractères, objet>Paramètres{ avoir; ensemble; } = Nouveau();
}

Maintenant, nous pouvons utiliser ceciParamètresdictionnaire pour stocker la configuration de l'un de nos composants de tableau de bord.

Index.razor (@code)

Tableau de bord DashboardConfig= Nouveau Configuration du tableau de bord
{Panneaux= Nouveau ListerPanneau>
    {
        Nouveau Panneau
        {Titre= "Contrer",Composant= nom de(Contrer)
        },
        Nouveau Panneau
        {Titre= "Temps",Composant= nom de(Récupérer les données),Paramètres= Nouveau dictionnairechaîne de caractères, objet> { ["Date de début"] = Nouveau DateHeure(2022,2,1) }
        }
    }
};

Récupérer les donnéesdans ce cas accepte unDate de débutparamètre.

WidgetsFetchData.razor

[Parameter] public DateHeure StartDate { obtenir ;  ensemble;  } = DateHeure.Maintenant ;

La dernière étape consiste à transmettre ces paramètres àComposant dynamique.

div classer="texte de la carte">
 @{ var componentType = ResolveComponent(@panel.Component);  si (typecomposant != null) {Composant dynamique Taper="componentType" Paramètres="@panel.Paramètres"/>
} }</div>

À partir de là, nous pouvons conserver cette configuration de tableau de bord dans une base de données (ou toute autre option de stockage) pour chaque utilisateur et nous avons notre tableau de bord personnalisable par l'utilisateur !

Avez-vous essayé le Telerik REPL pour Blazor ? C'est unnouvel outil Web pour la communauté Blazorcela permet d'écrire, d'exécuter, d'enregistrer et de partager rapidement et facilement des extraits de code.Vérifiez-le!




Source link