web-dev-qa-db-fra.com

Définissez la valeur de la variable sass dans Angular 7

J'ai travaillé avec angular au cours des dernières semaines, et maintenant j'ai besoin de styliser dynamiquement un site public. L'administrateur du site a défini divers codes de couleurs ainsi qu'une image de logo d'admin dans une base de données qui sera reflétée lors de l'ouverture du site public.

Comme je viens d'un arrière-plan asp.net, auparavant, je faisais le chargement de la page maître, prenais les valeurs de la base de données et les écrivais dans un fichier .less, et laissais la bibliothèque de scripts Java s'en occuper. C'est simple là-bas.

Mais pour ma situation actuelle, j'utilise sass, et je ne suis pas en mesure de trouver un moyen d'écrire des variables dans un fichier .scss.

Je viens d'apprendre une nouvelle chose APP_INITIALIZER de ici , mais finalement ce post ne montre pas comment écrire dans le fichier .scss.

En fait, je pense cela avec mes connaissances sur asp.net, mais je me trompe peut-être, ou il existe un autre moyen de mise en œuvre.

Je veux une solution simple, ce que nous faisons dans asp.net Je veux y parvenir de la même manière.

  1. Prenez la valeur variable de DB via api, lors du chargement de l'application pour la première fois.

  2. Écrivez les valeurs dans le fichier variable SASS.

  3. Après cela, SASS s'en occupera et nous obtiendrons les résultats escomptés.

Veuillez commencer par donner une suggestion ou un exemple.

Merci.

10
kuntal

Tout d'abord, dans ASP .NET, il n'est peut-être pas mauvais d'avoir une base de données pour conserver vos styles et autres actifs liés au frontal. Cela est dû au fait qu'il s'agit d'une infrastructure de rendu côté serveur. d'autre part, dans Angular, c'est côté client (à l'exception de Angular Universal, mais vous devrez toujours vous attendre à travailler avec les choses de la même manière). Même avec les traductions (i18n ou personnalisé), dans le monde Angular world, il est très probablement stocké à l'avant et non à l'arrière (db ou plus). Vous devrez donc aller chercher votre "thème" est stocké d'une certaine manière que vous préférez et faites votre chemin pour basculer entre eux dynamiquement avec Angular. Vous pouvez bien sûr stocker les clés/variables pour les styles/thèmes mais leurs valeurs CSS réelles (classes et autres) doivent être stockées sur le l'extrémité avant.

Essayez de voir cet exemple simple de vars CSS en cours d'utilisation tout en définissant dynamiquement le thème de l'application (angulaire) . Ce n'est qu'une façon et il existe de nombreuses façons de le faire et vous devrez peut-être rechercher vos préférences personnelles.

5
Cold Cerberus

Comme d'autres réponses l'ont expliqué, il n'est pas possible de définir des variables SASS et de les traiter sur le client, car SASS est converti en CSS simple au moment de la construction et lorsque l'application est en cours d'exécution ou dans le navigateur APP_INITIALIZER, il ne peut traiter que CSS.

Je vois deux options pour réaliser ce que vous voulez.

Généralement, vous auriez un CSS de base pour l'application, puis vous devez charger le CSS supplémentaire en fonction des paramètres d'administration. Ce qui doit être pris en compte du point de vue css, c'est que toute spécificité css dans les css supplémentaires doit être supérieure à la base css, car sinon elle ne remplacera pas la base. Cela nécessite des connaissances de base en CSS, donc je n'entrerai pas dans les détails.

Méthode 1

Générez votre CSS supplémentaire sur demande du serveur. Chargez-la au démarrage de l'application à partir de l'URL du serveur. Rechargez-le par js lorsque l'administrateur modifie les paramètres.

  1. Définissez le point de terminaison principal à l'adresse /additional.css (ou il pourrait être similaire à /api/theme/custom-css) qui générera des CSS à partir de la base de données. Par exemple, vous avez background=red en db, alors le point de terminaison devrait retourner
body {background-color: red;}
  1. Ajouter <link id="additionalCss" rel="stylesheet" type="text/css" href="additional.css" /> dans <head> de index.html. Et ce sera suffisant pour le faire fonctionner.
  2. Pour recharger, vous pouvez utiliser différentes méthodes, mais je pense que cela devrait fonctionner
document.getElementById('additionalCss').href = document.getElementById('additionalCss').href;

Cela fera une nouvelle demande au serveur, le serveur exécutera DB -> css et retournera le css mis à jour, qui sera appliqué au navigateur.

Et si vous voulez être cool (ou devez supporter des thèmes grands et complexes), scss peut être utilisé. Le backend doit générer des définitions de variables scss à partir de la base de données, puis utiliser une application côté serveur pour compiler scss -> css, puis renvoyer le css compilé au client. Mais ce sera exagéré si des CSS supplémentaires sont assez simples.

Une considération importante de cette méthode est la mise en cache du navigateur, car le contenu derrière additional.css est dynamique, mais le navigateur peut le mettre en cache, pas appeler le backend et servir une version obsolète.

Méthode 2

Si vous ne voulez pas ou ne pouvez pas jouer avec le backend. Chargez les paramètres de la base de données par un point de terminaison d'API dans json, puis générez du code CSS sur le client et appliquez-le.

  1. Utilisez HttpClient pour obtenir les paramètres JSON et générer des CSS comme chaîne à partir de celui-ci. Par exemple, le serveur renvoie
{
  "background": "red"
}

puis vous convertissez cela en chaîne comme

cssCode = 'body {background-color: red}';
  1. Utilisation
let additionalCssStyle = document.getElementById('additionalCss');
if (! additionalCssStyle) {
  additionalCssStyle = document.createElement("style");
  additionalCssStyle.id = 'additionalCss';
  document.head.appendChild(additionalCssStyle);
}
additionalCssStyle.innerText = cssCode;
  1. Pour recharger - enregistrer la modification dans le backend, puis répétez 1. et 2.
5
Ventzy Kunev

Alors que @ Cold Cerberus a suggéré une bonne approche et a raison de maintenir les choses liées au style à l'avant, je suggère quelques façons pour cela.

Comme vous avez dit que vous vouliez diverses combinaisons de couleurs, vous pouvez utiliser le CSS conditionnel de SASS.

body[theme="theme1"] {
   // theme 1 css
}

body[them="theme2"] {
    // theme 2 css
}

Vous pouvez utiliser carte de thème sass avec css conditionnel.

Il suffit de mettre à jour votre attribut et le thème sera appliqué automatiquement.

    themeChange() {
    const dom = document.querySelector('body');
    dom.theme = theme1;    // change theme here
    }

Si vous êtes très particulier au sujet d'un style d'élément qui devrait être mis à jour depuis le back-end (comme le code couleur), vous pouvez utiliser le style ng avec l'approche par thème.

<some-element [ngStyle]="{'font-style': styleExp}">...</some-element>

Vous devez utiliser une combinaison intelligente de ce qui précède afin de répondre à vos besoins.

3
Rajat Gupta

Je ne pense pas que ce que vous voulez sera possible de faire ... Angular traite les fichiers SASS lors de la construction de l'application et écrit tous les résultats communs dans un ancien css Le fichier spécifique au composant sera généré en javascript qui, à son tour, appliquera votre style au moment de l'exécution.

Par conséquent, toutes les variables SASS que vous devez configurer doivent être présentes au moment de la compilation.

Ce que vous pouvez faire, cependant, est de prédéfinir votre configuration dans Angular, puis de la basculer en fonction d'une entrée (depuis votre base de données ou ailleurs), comme ceci:

// your.component.ts
@Component({
  // ... component stuff
  styles: ['h1.option1 {color: red;}', 'h1.option2 {color: blue;}'],
  template: `
    <h1 *ngIf="optionSelection$ | async as option; else noOption"
        [class.option1]="option == 1" 
        [class.option2]="option == 2">
       Hey there, I'm styled!
    </h1>
    <ng-template #noOption>
      <h1>No option received</h1>
    </ng-template>
  `
})
export class YourComponent {
  optionSelection$: Observable<number>;
  constructor(yourService: YourService){
    this.optionSelection$ = yourService.getYourOption().pipe(startWith(null));
  }
}

Espérons que cela aide un peu :-)

2
Heehaaw

Ce n'est pas possible de cette façon, mais plutôt que d'utiliser la variable sass, vous utilisez la valeur de la variable sass. Cela peut avoir n'importe quelle valeur.

Pourquoi? parce que sass est compilé lors de l'empaquetage et à la fin, il générerait toujours un CSS plan.

Un exemple de cadre utilisant ce processeur de style facultatif est angulaire.


Dans votre cas, je recommanderais d'examiner la thématique dynamique dans angular car ce dont vous avez besoin a certainement besoin de JavaScript. Consultez le guide sur le support donné par l'un des contributeurs.

https://stackoverflow.com/a/54559350/3070499

0
Joseph118

Puisque sass est un CSS pré-compilé. nous ne pouvons pas changer dynamiquement le thème sans générer un theme.css séparé. C'est là que JSS vient de jouer. JSS est un mécanisme d'injection de style basé sur javascript, où les CSS sont directement injectés dans les fichiers que vous utilisez.

react-angular-material l'utilise intensivement, où nous pouvons passer dynamiquement des variables de couleur à changer le thème de l'application.

par exemple, ce type l'a fait avec angulaire .

Documents: jss-angular , jss

liens: jss-with-angular

0
Mukundhan