Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Twitter bootstrap Angular 4 CLI,WebPack,为整个网站动态切换引导主题_Twitter Bootstrap_Angular_Webpack_Sass_Angular Cli - Fatal编程技术网

Twitter bootstrap Angular 4 CLI,WebPack,为整个网站动态切换引导主题

Twitter bootstrap Angular 4 CLI,WebPack,为整个网站动态切换引导主题,twitter-bootstrap,angular,webpack,sass,angular-cli,Twitter Bootstrap,Angular,Webpack,Sass,Angular Cli,我想为用户提供一个按钮,以改变整个网站的主题。我正在使用bootstrap.scss文件进行所有操作。 以下是我所做的: 我在src/styles文件夹中有dark-styles.scss和light-styles.scss。这两个文件都覆盖了我需要覆盖的类和方法,还从节点模块导入了bootstrap.scs作为默认值。当我通过下面的.angular-cli.json向应用程序提供这些文件时;它工作得很好 "styles": [ "../node_modules/font-awe

我想为用户提供一个按钮,以改变整个网站的主题。我正在使用bootstrap.scss文件进行所有操作。 以下是我所做的:

我在src/styles文件夹中有dark-styles.scss和light-styles.scss。这两个文件都覆盖了我需要覆盖的类和方法,还从节点模块导入了bootstrap.scs作为默认值。当我通过下面的.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"
      ],
或者

如果我提供黑暗,主题是黑暗的,如果我提供光明,主题是光明的

但我想要实现的是动态地允许用户更改主题。因此,基于stackoverflow中的其他答案;我访问了我的应用程序组件中的文档,它也是我的根组件。它让我可以访问整个html页面,在那里我有一个链接标签,我可以从应用程序组件设置

HTML文件

<head>
<link id="theme" type="text/scss" rel="stylesheet" src="">
</head>
<body>
content .....
</body>
应用程序组件:

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');
        }
      }
    }

触发事件handleChangeTheme时,html文件中主题更改的href。但它不会更新或应用样式。我知道这与WebPack及其编译scss文件的方式有关。有没有人遇到过类似的情况,或者知道这个问题的解决方法。谢谢

我刚刚在本地完成了您的示例,在我将type=text/scss更改为text/css之后,似乎对type=text/scss存在问题,因为它开始工作了。我认为首先你们需要重新创建元素,但问题似乎和类型有关

由于它的主题,我建议您使用这些文件的编译css版本将它们放入assets文件夹,angular cli将在serve和build上复制它们


此外,当您在angular 4+引导中引用SCS时,它会使用Web包编译为css。

我使用以下方法在angular 4+引导中获得动态主题:

使用地图定义的主题颜色:

然后,创建以下mixin以输出每个主题名称和给定属性的颜色:

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

@mixin background-color($arguments...) {
  @include themify('background-color', $arguments...);
}
我使用mixin来控制各个属性:

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

@mixin background-color($arguments...) {
  @include themify('background-color', $arguments...);
}
对于每个主题化组件,我在声明属性时必须使用上面的mixin:

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

@mixin background-color($arguments...) {
  @include themify('background-color', $arguments...);
}
CSS输出类似于:

最后,要使主题可用,您必须控制某个父组件中的主题类:


经过几个小时的尝试,我终于让bootstrap主题切换程序开始工作。以下是我的解决方案:

不要使用bootswatch.scss,而是下载每个主题的编译版本,将它们放在同一个资产文件夹中,并相应地重命名文件。 将此行添加到index.html。选择默认主题:

< link id="theme" type="text/css" rel="stylesheet" href="/assets/css/theme_slate_bootstrap.min.css">
...
...
<body class="theme-slate">
...
切换主题的按钮

<div style="display:block; position: absolute; top:0; right:0; text-align:right; z-index:100000;">
    <button class="btn btn-primary btn-sm" (click)="theme('slate')">Slate</button>
    <button class="btn btn-secondary btn-sm" (click)="theme('yeti')">Yeti</button>
    <button class="btn btn-secondary btn-sm" (click)="theme('darkly')">Darkly</button>
</div>
custom.scss-在此处添加自定义代码

$themes: (
    slate: (
        name: 'slate',
        primary: #3A3F44,
        secondary: #7A8288,
        ...
    ),
    yeti: (
        name: 'yeti',
        primary: #008cba,
        secondary: #eee,
        ...
    ),
    darkly: (
        name: 'darkly',
        primary: #008cba,
        secondary: #eee,
        ...
    ),
);

/*
* Implementation of themes
*/
@mixin themify($themes) {
    @each $theme, $map in $themes {
        .theme-#{$theme} & {
        $theme-map: () !global;
        @each $key, $submap in $map {
            $value: map-get(map-get($themes, $theme), '#{$key}');
            $theme-map: map-merge($theme-map, ($key: $value)) !global;
        }
        @content;
        $theme-map: null !global;
        }
    }
}

@function themed($key) {
    @return map-get($theme-map, $key);
}


* {
    @include themify($themes) {
        // custom theme to your needs. Add here
        @if themed('name') == 'slate' {
        }


        @if themed('name') == 'yeti' {
        }


        @if themed('name') == 'darkly' {
        }


        // Below will effect all themes
        .btn, .form-control, .dropdown, .dropdown-menu {
            border-radius: 0;
        }

        // This is just example to code. When switching theme, primary button theme should changed. Below code is not required. 
        .btn-primary {
            background-color: themed('primary');
            border-color: themed('primary');
        }

    }
}
// ***********************************************************************

@import "custom-additional-classes";

希望这能帮助所有寻求bootstrap themes switcher解决方案的人

我想你必须编译这两个scss文件,并使它们可供应用程序选择,即将它们打包到你的webapp@ochi ... 我也试过了。。。没用。执行此操作时,会应用默认引导,覆盖被全部拒绝。您解决了吗?我被指派做同样的事情。任何帮助都会很感激的,我暂时把它放在一边。。。。。在materialWebpack中很容易实现这一点,它使用一个处理器来转换Sass->CSS。假设路径和文件类型正确,这似乎与右上角Material doc paint bucket使用的技术相同,选择link.style-manager-theme的主题更新href:我开始悬赏这个问题,因为我有同样的问题。我最后用另一种方法解决了这个问题,更准确地说,类似这样的方法:@MarcusVinicius-对你的方法进行更详细的解释会有所帮助。您是否按照Volodymyr Bilyachat的建议将SCS预编译为css?这是使用angular cli本身实现的,还是您必须添加一些手动节点sass命令才能使htis正常工作?您如何使用链接切换主题?正如Virodh最初提出的?@RafiAliKhan,我添加了一个更详细的答案,解释了我是如何让动态主题工作的。
.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>
@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;
    }
}
< link id="theme" type="text/css" rel="stylesheet" href="/assets/css/theme_slate_bootstrap.min.css">
...
...
<body class="theme-slate">
...
    import { Component, OnInit, Renderer2, Inject } from '@angular/core';
    import { DOCUMENT } from '@angular/platform-browser';

    @Component({
    selector: 'apps',
    templateUrl: './app.component.html'
    })
    export class AppComponent implements OnInit, OnDestroy {
        private currentTheme: string = 'slate';

        constructor(private renderer: Renderer2, @Inject(DOCUMENT) private document) { }

        ngOnInit() {}

        theme(type) {
            this.renderer.removeClass(document.body, 'theme-'+this.currentTheme);
            this.currentTheme = type;
            this.renderer.addClass(document.body, 'theme-'+this.currentTheme);
            this.document.getElementById('theme').href = '/assets/css/theme_'+type+'_bootstrap.min.css';
        }
    }
<div style="display:block; position: absolute; top:0; right:0; text-align:right; z-index:100000;">
    <button class="btn btn-primary btn-sm" (click)="theme('slate')">Slate</button>
    <button class="btn btn-secondary btn-sm" (click)="theme('yeti')">Yeti</button>
    <button class="btn btn-secondary btn-sm" (click)="theme('darkly')">Darkly</button>
</div>
"styles": [
    "src/assets/scss/custom.scss"
],
$themes: (
    slate: (
        name: 'slate',
        primary: #3A3F44,
        secondary: #7A8288,
        ...
    ),
    yeti: (
        name: 'yeti',
        primary: #008cba,
        secondary: #eee,
        ...
    ),
    darkly: (
        name: 'darkly',
        primary: #008cba,
        secondary: #eee,
        ...
    ),
);

/*
* Implementation of themes
*/
@mixin themify($themes) {
    @each $theme, $map in $themes {
        .theme-#{$theme} & {
        $theme-map: () !global;
        @each $key, $submap in $map {
            $value: map-get(map-get($themes, $theme), '#{$key}');
            $theme-map: map-merge($theme-map, ($key: $value)) !global;
        }
        @content;
        $theme-map: null !global;
        }
    }
}

@function themed($key) {
    @return map-get($theme-map, $key);
}


* {
    @include themify($themes) {
        // custom theme to your needs. Add here
        @if themed('name') == 'slate' {
        }


        @if themed('name') == 'yeti' {
        }


        @if themed('name') == 'darkly' {
        }


        // Below will effect all themes
        .btn, .form-control, .dropdown, .dropdown-menu {
            border-radius: 0;
        }

        // This is just example to code. When switching theme, primary button theme should changed. Below code is not required. 
        .btn-primary {
            background-color: themed('primary');
            border-color: themed('primary');
        }

    }
}
// ***********************************************************************

@import "custom-additional-classes";