在Angular2中为组件加载多个样式表

8

我正在构建一个angular2应用程序。当我尝试为同一组件加载多个样式表时,我遇到了多个问题。以下是我正在做的代码:

import { Component } from '@angular/core';

@Component({
selector: 'my-tag',
templateUrl: 'my-tag.component.html',
styleUrls: [
    './style1.css',
    './style2.css'
    ]
})
export class MyTagComponent{}

现在我遇到的问题是:
当我尝试从其他目录包含css文件时,像这样:
styleUrls: [
    './style1.css',
    '../public/style2.css'
]

我在浏览器控制台中看到以下错误:

Uncaught Error: Expected 'styles' to be an array of strings.

接下来,我将第二个样式表 style2.css 放在组件的目录中,并编写了第一个代码片段。现在样式被加载了,但是它是全局加载的。第二个样式表具有与 bootstrap 冲突的类名,因此全局应用了第二个样式表的样式,即其他组件的模板也从第二个样式表中进行了样式设置。

按理说,styleUrls 中列出的 URL 应该仅应用于该组件,不会影响其他组件,但事实却并非如此。

请问有没有人能告诉我如何为特定组件加载多个 CSS 文件而不会全局应用?我已经尝试了以下解决方法,但样式仍然被应用到我创建的所有组件上。

styles: [
      require('./style1.css').toString(),
      require('../public/style2.css').toString()
 ]

P.S. 我正在将webpack作为项目的模块打包工具。
webpack配置(摘录)
 {
    test: /\.css$/,
    exclude: helpers.root('src', 'app'),
    loader: ExtractTextPlugin.extract('style', 'css?sourceMap')
  },
  {
    test: /\.css$/,
    include: helpers.root('src', 'app'),
    loader: 'raw'
  }
3个回答

20

我曾经看到过这种方法的使用:

@Component({
    selector: 'app',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
}

app.component.css中有多个导入,因此:

@import url('/assets/plugins/bootstrap-datepicker/css/bootstrap-datepicker.css');
@import url('/assets/plugins/bootstrap-datepicker/css/bootstrap-datepicker3.css');
@import url('/assets/plugins/ionRangeSlider/css/ion.rangeSlider.css');
@import url('/assets/plugins/ionRangeSlider/css/ion.rangeSlider.skinNice.css');

我希望这有所帮助。


在当前版本的Angular 4中,你不能只在全局styles.css文件中执行那些导入语句吗? - rosstripi
1
@davaus 这不是有点违背在 styleUrls 中将值作为数组传递的目的吗?元数据本身就暗示了多个样式表。 - kanra-san
嗨,Kanra-san。我同意;但是数组不起作用(我试过了),而这种方法却可以...... - davaus

3
我们通过设置templateUrl和styleUrls元数据属性来包含模板和CSS文件。由于这些文件与组件共存,因此最好通过名称引用它们,而不必指定返回应用程序根目录的路径。
我们可以通过将组件元数据的moduleId属性设置为module.id来更改Angular计算完整URL的方式。
@Component({
  selector: 'my-tag',
  moduleId: module.id,
  templateUrl: 'my-tag.component.html',
  styleUrls:  ['style1.css', 'style2.css']
})
export class MyTagComponent { }

更新#1

针对webpack:

尝试在webpack配置中使用'to-string-loader'来处理css。

{ test: /\.css$/, loaders: ['to-string-loader', 'css-loader'] }

希望对您有所帮助。


我正在使用webpack作为模块打包工具。你的解决方案适用于使用systemjs作为模块打包工具的情况。 - kanra-san
我已经更新了webpack,请查看上面的更新#1。谢谢。 - Avnesh Shakya
我尝试了你的配置,但没有成功。 我已经在上面发布了我的webpack.config。 如果我错了,请纠正我,但to-string-loader不是和toString()做相同的工作吗? 正如我在上面提到的,当我添加toString()时,样式表被加载了,但它会被全局加载,并影响其他每个组件。 - kanra-san
尝试在组件元标记中添加 encapsulation: ViewEncapsulation.None,你需要导入它 => import {ViewEncapsulation} from '@angular/core'; 点击这里查看。 - Avnesh Shakya
实际上,我已经尝试过那个方法,但也没有用。 - kanra-san

0

我认为问题出在你传递给ExtractPlugin.extract(loader: options|object)的'style'参数上。我想它指的是这个loader: https://github.com/webpack/style-loader,它会向DOM添加一个样式标签,因此会全局应用你的样式。

我前几天遇到了这个问题,只是为了这篇文章查找了上述理由,应该回去并根据这个理由正确地解决它,但我通过简单地使用css-loader来解决了它:

  {
    test: /\.css$/,
    loader: "css-loader"
  }

同时将封装设置为ViewEncapsulation.Native,并在加载的CSS上调用.toString(),正如您之前注意到的那样。虽然我想ExtractTextPlugin仍然可以使用,但需要删除'style' loader。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接