假设我们想在angular2中使用某个库中的组件(例如来自material2) . 组件注释如下所示:
@Component({
moduleId: module.id,
selector: 'md-input',
templateUrl: 'input.html',
styleUrls: ['input.css'],
providers: [MD_INPUT_CONTROL_VALUE_ACCESSOR],
host: {'(click)' : 'focus()'}
})
该组件附带“默认”样式表,即“input.css” . 如果我们在应用程序中使用此组件,我们可能希望覆盖/扩展某些样式,而无需复制和操作组件本身 . 这该怎么做?
Possible Solution 1: Set the Encapsulation to "ViewEncapsulation.None":
这不是一个真正的解决方案,只是一种解决方法 .
Possible Solution 2: Use "::shadow" or "/deep/" in CSS:
也可以,但根据WebComponent规范弃用了它 .
Possible Solution 3: Use global CSS and override the component CSS:
也可以,但它违反了影子DOM概念 .
Possible Solution 4: Override directly in the template of parent component:
例:
<my-cmp [font-size]="100"></my-cmp>
如果我们做了很多重写,那真的不合适 .
Possible Solution 5: Override or extend the "@Component" definition with an additional stylesheet somehow:
这似乎是唯一正确的解决方案(至少对我而言) . 但我不知道该怎么做......
有什么建议吗?也许我弄错了...谢谢 .
4 回答
对于解决方案5,您需要为目标组件创建一个子类,创建一个自定义装饰器来处理/覆盖元数据并为当前子组件设置它 .
这是一个示例:
CustomComponent
装饰器看起来像这样:有关详细信息,请参阅此问题:
在Angular 4中,我们可以使用继承的类样式表中的
::ng-deep
伪类选择器覆盖样式 .有关更多信息,请参阅http://blog.angular-university.io/angular-ngclass-ngstyle/
这仅适用于
ViewEncapsulation.Native
.如果您使用
ViewEncapsulation.Emulated
(默认),则Angular使用它自己对/deep/
和::shadow
的解释,并且不适用弃用 .如果您使用
ViewEncapsulation.Native
,那么您目前运气不佳,因为浏览器原生::shadow
和/deep/
深度已被弃用,而Angular尚未提供对ViewEncapsulation.Native
的主题支持的任何支持,例如Polymer使用(polyfilled)CSS变量和mixins .从Angular 2.3开始,我们可以使用组件继承 . 为了完成您的解决方案5,我们可以做到这一点 .