使用不同的 CSS 样式表动态更改 Angular 组件的样式
Dynamically changing the style of an Angular component using different CSS style sheets
我正在尝试获取动态样式 -sheet 更改,以便在 Angular 中工作的单页应用程序。这个想法是创建不同的主题,并让用户在专用菜单中从中进行选择。可能有很多主题,所以不要介意下面的示例只有两个变体。功能已准备就绪。截至目前,我已将所有样式收集在单个大型 scss 文件中,每个主题一个。 (请注意,我很清楚在 Angular 中,您经常将样式拆分为每个组件的许多子 scss 文件。但是为了实现这个想法,我想将每个主题的所有样式都放在一个文件中) .我让菜单正常工作,并为应用程序使用本地存储来记住选择了哪个主题,因为必须重新加载站点才能使更改生效。
现在问题来了:
在 app.component.ts 中,样式 sheet 以标准格式定义(即 styleUrls: [filename])。当在那里使用静态文件 path/name 时,以及使用在 @component-code 之外定义的变量时,样式可以完美运行。但是对于动态主题更改,我从本地存储中简单地获取了变量:
var settingsString = localStorage.getItem('usergraphicsdata');
if (isDefined(settingsString)) {
let myUserSettings = JSON.parse(settingsString);
const themename = myUserSettings.theme;
在那里也一切正常。不同的 console.logs 确认它理解它应该理解的一切。但是问题来了。
if(themename == "theme1"){
var stylePath = "./app.component_theme1.scss";
var graphicFolder = '/assets/theme1/';
} else if(themename == "theme2"){
var stylePath = "./app.component_theme2.scss";
var graphicFolder = '/assets/theme2/';
}
}
然后是带有 styleUrls 的 @component:[stylePath]
出于某种原因,if 条件未被考虑,结果始终是第一个声明的主题(在上述情况下为“theme1”)将处于活动状态。因此,如果我只是更改条件中的顺序,并将主题 2 的代码放在首位,将为该站点选择该代码,而不管实际从 localstorage
中获取哪个主题变量
我也尝试过其他几种变体,但这个似乎最接近解决方案。 Angular 限制运行时对比构建中的样式更改可能是一个问题吗?还是我忘记了 if 条件中的一些基本内容?
最好的问候和抱歉我的英语有限。
每
为什么不用路由解决呢?为每个主题复制组件,只是使用不同的 css-文件,但对所有这些组件使用相同的 html-文件,并在菜单中为该组件放置一个 link(带有具体主题)。附加值是主题名称也出现在 url 中,您可以轻松应用不同的逻辑,而不会令人费解(不同的打字稿文件)。
像这样:
@Component({
selector: 'sunflower',
templateUrl: './detail.component.html',
styleUrls: ['./sunflower.component.scss']
})
export class SunflowerComponent {
@Component({
selector: 'roses',
templateUrl: './detail.component.html',
styleUrls: ['./roses.component.scss']
})
export class RosesComponent {
如果您尝试过,请分享您遇到的问题。
更新
我做了一个非常基本的演示(我已经测试过了),你可以在这里找到它:
保重,祝你好运。
我正在尝试获取动态样式 -sheet 更改,以便在 Angular 中工作的单页应用程序。这个想法是创建不同的主题,并让用户在专用菜单中从中进行选择。可能有很多主题,所以不要介意下面的示例只有两个变体。功能已准备就绪。截至目前,我已将所有样式收集在单个大型 scss 文件中,每个主题一个。 (请注意,我很清楚在 Angular 中,您经常将样式拆分为每个组件的许多子 scss 文件。但是为了实现这个想法,我想将每个主题的所有样式都放在一个文件中) .我让菜单正常工作,并为应用程序使用本地存储来记住选择了哪个主题,因为必须重新加载站点才能使更改生效。
现在问题来了: 在 app.component.ts 中,样式 sheet 以标准格式定义(即 styleUrls: [filename])。当在那里使用静态文件 path/name 时,以及使用在 @component-code 之外定义的变量时,样式可以完美运行。但是对于动态主题更改,我从本地存储中简单地获取了变量:
var settingsString = localStorage.getItem('usergraphicsdata');
if (isDefined(settingsString)) {
let myUserSettings = JSON.parse(settingsString);
const themename = myUserSettings.theme;
在那里也一切正常。不同的 console.logs 确认它理解它应该理解的一切。但是问题来了。
if(themename == "theme1"){
var stylePath = "./app.component_theme1.scss";
var graphicFolder = '/assets/theme1/';
} else if(themename == "theme2"){
var stylePath = "./app.component_theme2.scss";
var graphicFolder = '/assets/theme2/';
}
}
然后是带有 styleUrls 的 @component:[stylePath]
出于某种原因,if 条件未被考虑,结果始终是第一个声明的主题(在上述情况下为“theme1”)将处于活动状态。因此,如果我只是更改条件中的顺序,并将主题 2 的代码放在首位,将为该站点选择该代码,而不管实际从 localstorage
中获取哪个主题变量我也尝试过其他几种变体,但这个似乎最接近解决方案。 Angular 限制运行时对比构建中的样式更改可能是一个问题吗?还是我忘记了 if 条件中的一些基本内容?
最好的问候和抱歉我的英语有限。 每
为什么不用路由解决呢?为每个主题复制组件,只是使用不同的 css-文件,但对所有这些组件使用相同的 html-文件,并在菜单中为该组件放置一个 link(带有具体主题)。附加值是主题名称也出现在 url 中,您可以轻松应用不同的逻辑,而不会令人费解(不同的打字稿文件)。
像这样:
@Component({
selector: 'sunflower',
templateUrl: './detail.component.html',
styleUrls: ['./sunflower.component.scss']
})
export class SunflowerComponent {
@Component({
selector: 'roses',
templateUrl: './detail.component.html',
styleUrls: ['./roses.component.scss']
})
export class RosesComponent {
如果您尝试过,请分享您遇到的问题。
更新
我做了一个非常基本的演示(我已经测试过了),你可以在这里找到它:
保重,祝你好运。