问题
I'm looking to implement a theme in my Angular (5) webapp. I'm not using Angular Material for everything (I.e. I only use the input fields and certain components)
I'm looking for a theming solution I can use/control/change at runtime, and not have to recompile my app.
I use SCSS/Sass.
What I've done currently: (In a very basic example)
variables.scss
$color-1: #fff;
$color-2: #000;
test-component/test-component.scss
@import "../variables.scss";
.test {
color: $color-1;
border: 1px solid $color-2;
}
Since I started development on my app I simply assigned values to SCSS variables and used them, but a little down the line I'd like to implement a decent theming solution where I can control the theme during run time, as variables are only set at compilation time.
Additional things I've looked into:
I came across this article which seems like a decent idea to implement, however at a component level I'm not entirely sure how effective it'll be since deeply nested components would not be able to see what a class a container surrounding their router would be, for instance.
Any other ideas? Just to reiterate, I'm not looking to modify the Angular Material theme I have.
EDIT 1:
I came across this magical post, will do some coding in the morning and see what I can do with it.
回答1:
Eureka!
So the solution I formulated in the end works pretty well, allowing me to modify my existing SASS for each component I want themed with ease.
I took the concept used here and modified the helper functions to cater for any amount of keys you might want to look up in your theme (instead of just 2 levels like the example).
To get it working in the context of an Angular application like I did, I used the :host-context selector:
@mixin theme-this($themes: $themes) {
@each $theme-name, $theme in $themes {
:host-context(.theme-#{$theme-name}) & {
$theme-map: $theme !global;
@content;
$theme-map: null !global;
}
}
}
Then in your base component, wrap all of your content in a div with the relevant theme class (.theme-x) and any generated CSS with a class matching the one currently applied to your base component will automatically be rendered in the browser.
One cool thing about handling your theme like this is you can change it at run time.
I added a theme service to contain the currently selected theme, which I'll modify at a later stage to store the theme in your browsers local storage/user cookie/etc.
来源:https://stackoverflow.com/questions/49862993/angular-theming