2017-06-22 78 views
7

我想爲用戶提供一個按鈕來更改整個網站的主題。我正在使用bootstrap「.scss」文件。 以下是我所做的:Angular 4 CLI,WebPack,爲整個網站動態切換引導主題

我在「src/styles」文件夾中有「dark-styles.scss」和「light-styles.scss」。這兩個文件都會覆蓋我需要覆蓋的類和方法,並且還會從「node-module」中導入默認值「bootstrap.scss」。當我通過下面的「.angular-cli.json」嚮應用程序提供這些文件時,它完美地工作。

"styles": [ 
     "../node_modules/font-awesome/css/font-awesome.css", 
     "../node_modules/@swimlane/ngx-datatable/release/index.css", 
     "../node_modules/@swimlane/ngx-datatable/release/assets/icons.css", 
     "../src/styles/dark-styles.scss" 
     ], 

,或者

"styles": [ 
     "../node_modules/font-awesome/css/font-awesome.css", 
     "../node_modules/@swimlane/ngx-datatable/release/index.css", 
     "../node_modules/@swimlane/ngx-datatable/release/assets/icons.css", 
     "../src/styles/light-styles.scss" 
     ], 

如果我提供黑暗中的主題是黑暗的,如果我提供光的主題是光。

但我想實現的是動態地允許用戶更改主題。因此,基於stackoverflow中的其他答案;我訪問了我的應用程序組件中的「文檔」,這也是我的根組件。它使我可以訪問整個html頁面,在那裏我可以從應用程序組件中設置一個鏈接標記。

HTML文件

<head> 
<link id="theme" type="text/scss" rel="stylesheet" src=""> 
</head> 
<body> 
content ..... 
</body> 

角cli.json

"styles": [ 
     "../node_modules/font-awesome/css/font-awesome.css", 
     "../node_modules/@swimlane/ngx-datatable/release/index.css", 
     "../node_modules/@swimlane/ngx-datatable/release/assets/icons.css" 
     ], 

應用組分:

import { Component, OnInit, Inject } from '@angular/core'; 
import { DOCUMENT } from '@angular/platform-browser'; 

@Component({ 
    selector: 'app-root', 
    templateUrl: './app.component.html', 
     styleUrls: ['./app.component.scss'], 
    }) 
    export class AppComponent implements OnInit { 
     currentTheme: string; 

     constructor(@Inject(DOCUMENT) private document) { 
     } 

     ngOnInit() { 
     this.currentTheme = 'dark'; 
     this.document.getElementById('theme').href = '../styles/dark-styles.scss'; 
     } 

     handelChangeTheme(event) { 
     if (this.currentTheme === 'dark') { 
     this.document.getElementById('theme').href = '../styles/light-styles.scss'; 
      this.currentTheme = 'light'; 
      console.log('light'); 
     } else { 
     this.document.getElementById('theme').href = '../styles/dark-styles.scss'; 
      this.currentTheme = 'dark'; 
      console.log('dark'); 
     } 
     } 
    } 

雖然觸發了#theme變化的情況下 「handleChangeTheme」 在href在html文件中。但它不更新或應用樣式。我知道這與WebPack和編譯scss文件的方式有關。有沒有人遇到類似的情況或知道解決這個問題的方法。謝謝

+0

我猜你必須編譯這兩個scss文件,並讓它們可供應用程序選擇(即把它們包裝到你的webapp中) – ochi

+0

@ochi ...試過了......沒有工作。在這樣做的時候,應用默認的引導程序覆蓋全部被拒絕。 – Virodh

+0

你解決了嗎?我被分配去做同樣的事情。任何幫助將不勝感激 –

回答

6

我剛剛在本地完成你的例子,似乎是type="text/scss"問題後,我改變它text/css它開始工作。我認爲,首先,你需要重新創建元素,但問題似乎與類型

因爲它的主題,我會建議你使用這些文件的編寫CSS版本把它們放到assets文件夾和角CLI將複製他們servebuild

此外當你在你的角度引用scss與webpack編譯爲CSS。

+0

因爲我遇到了同樣的問題,所以我在這個問題上開始了賞金。我最終用另一種方法解決了問題,更準確地說,類似於以下內容:https://www.sitepoint.com/sass-theming-neverending-story/ – MarcusVinicius

+0

@MarcusVinicius - 對您的方法更詳細的解釋會有所幫助。你是否預先將scss編譯爲css(如Volodymyr Bilyachat所建議的) - 使用angular-cli本身會發生這種情況,還是必須添加一些手動節點sass命令才能使用htis ....以及如何切換主題(使用鏈接?最初由Virodh提議?) –

+0

@RafiAliKhan,我添加了一個關於如何獲得動態主題工作的更詳細解釋的答案。 – MarcusVinicius

1

我設法通過以下方法來獲得角4 +引導動態主題工作:

定義主題顏色使用地圖:

$themes: (
    alpha: (
     primary: #2b343e, 
     info: #3589c7, 
     top-color: #000000, 
     top-font-color: #ffffff, 
     ... 
    ), 
    beta: (
     primary: #d2a444, 
     info: #d2a444, 
     top-color: #ffffff, 
     top-font-color: #000000, 
     ... 
    ) 
) 

然後,創建了以下的mixin爲每個主題名稱和屬性輸出顏色

我用混入來控制單個屬性:

@mixin color($arguments...) { 
    @include themify('color', $arguments...); 
} 

@mixin background-color($arguments...) { 
    @include themify('background-color', $arguments...); 
} 

對於每個 「主題化」 組分,我不得不使用聲明時性能高於混入

.page-top { 
    @include background-color('top-color'); 
    @include color('top-font-color');  
    height: 66px; 
    width: 100%; 
    ...  
} 

的CSS輸出會是這樣的:

.page-top { 
    height: 66px; 
    width: 100%; 
    ...  
} 

.page-top.theme-alpha, 
.theme-alpha .page-top { 
    background-color: #000000; 
    color: #ffffff; 
} 

.page-top.theme-beta, 
.theme-beta .page-top { 
    background-color: #ffffff; 
    color: #000000; 
} 

最後,爲了使主題可用,你必須控制在一些父母的組件的主題類:

<!-- class="theme-alpha" --> 
<main themeChange> 
    <page-top></page-top> 
    <sidebar></sidebar> 
    <page-bottom></page-bottom> 
</main> 

themeChange指令可以這樣寫:

@Directive({ 
    selector: '[themeChange]' 
}) 
export class ThemeChange implements OnInit { 
    @HostBinding('class') classes: string; 
    private _classes: string[] = []; 

    ngOnInit() {   
     // grab the theme name from some config, variable or user input 
     this.classesString = myConfig.theme; 
    } 
}