【问题标题】:Angular 2 css styles leaking out of componentAngular 2 css 样式从组件中泄漏出来
【发布时间】:2017-05-09 13:56:47
【问题描述】:

Plunker with the problem I'm having. "如果您注释掉 ThirdComponent 中的样式,您可以看到它会影响父组件和兄弟组件的样式。" – adriancarriger(谢谢阿德里安)

在我正在使用的组件中...

styles: ['
    @import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css";
    @import "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.43/css/bootstrap-datetimepicker.min.css";
']

但它似乎破坏了任何调用它的组件的样式。我只需要这一个组件中的样式。我认为 Angular 2 组件是完全独立的,不知道为什么这个组件会改变我的整个 Web 应用程序。

组件:

import { Component, OnInit } from '@angular/core';
import datetimepicker from 'eonasdan-bootstrap-datetimepicker';
import moment from 'moment';


@Component({
    selector: 'date-time-picker',
    styleUrls: ['../../../css/datetimepicker.css'],
    template:` 
                    <div class="input-group">
                        <input class="form-control" 
                        a2e-datetimepicker
                        [date]="date"
                        [options]="a2eOptions"
                        (onChange)="dateChange($event)"
                        (onClick)="dateClick()"
                        />
                        <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
                    </div>
    `
})
export class DateTimePicker implements OnInit {

  date: moment.Moment;
  a2eOptions: any;

  dateChange(date) {
    this.date = date;
  }

  dateClick() {
    console.log('click click!')
  }

  getTime() {
    alert('Selected time is:' + this.date);
  };

  addTime(val, selector) {
    this.date = moment(this.date.add(val, selector));
  };

  clearTime() {
    this.date = null;
  };

  constructor(){
        this.date = moment();
        this.a2eOptions = {
            format: 'dddd, MMMM Do YYYY, h:mm a',
            //sideBySide: true,
            stepping: 5
        };
  }

  ngOnInit(): void {
    console.log(datetimepicker);
  }

}

日期时间选择器.css

@import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css";
@import "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.43/css/bootstrap-datetimepicker.min.css";

如果我这样做,结果相同:

template:` 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.43/css/bootstrap-datetimepicker.min.css">

使用 systemJS

【问题讨论】:

  • 你也可以发布你的组件吗?
  • 您的组件封装应该是 Emulated 或 Native
  • 现在有组件了。
  • 这不可能已经流血了,你确定你没有在其他地方导入过这种样式吗?就像在您的应用程序或 index.html 或其他地方一样?
  • 这是一个最小的plunker example.. 如果您注释掉ThirdComponent 中的样式,您可以看到它会影响父组件和兄弟组件的样式。

标签: css angular components


【解决方案1】:

关于组件样式的视图封装通过扩展现有选择器 使用 angular 添加的自定义属性来工作。

例子:

宿主元素变为&lt;my-thrid-component _nghost-dra-1&gt;
它所有的孩子都变成了例如&lt;h3 _ngcontent-dra-1&gt;.

Angular 现在采用你的 css 选择器并扩展它们:

h3 { ... } 变为 h3[_ngcontent-dra-1] { ... },因此您的样式仅适用于组件本身的元素。

现在回到扩展现有选择器部分。
当您@import 一个外部文件时,它的内容不会被提取 - 该文件将作为外部资源加载,因此 Angular 无法修改它。

查看生成的style 标签,了解实际情况:

<style>
  @import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css";
  @import "https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.43/css/bootstrap-datetimepicker.min.css";

  h1[_ngcontent-dra-1],
  h2[_ngcontent-dra-1],
  h3[_ngcontent-dra-1] {
    background: red;
  }
</style>

结论:不存在嵌套导入之类的东西,因此导入的样式全局应用。如果你真的想只包含特定组件的样式,你需要让它们在本地可用,这样 Angular 可以读取它的内容并扩展选择器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-31
    • 1970-01-01
    • 2016-04-25
    相关资源
    最近更新 更多