将弹性规则应用于多个 Angular 4 个组件的通用解决方案

Generalized solution for applying flex rules to multiple Angular 4 components

我的应用程序中有多个选项卡和子选项卡,每个选项卡和子选项卡都是一个组件。他们需要随着可用 space 的增长或收缩而增长和收缩。

实现灵活布局的一个关键步骤是在我的应用程序级别 CSS 文件中为主应用程序的所有子组件设置以下主要 CSS 规则:

/* app-level.component.css */
:host ::ng-deep tab1,
:host ::ng-deep tab2,
:host ::ng-deep tab1-subtab1,
:host ::ng-deep tab1-subtab2 {
{
  display: flex;
  flex: 1 1 auto;
  flex-flow: column nowrap;
}

其中 tab1tab2tab1-subtab1tab1-subtab2 选择器 例如对于选项卡 1:

/* tab1.component.ts */
@Component({
  selector: 'tab1',
  templateUrl: './tab1.component.html',
  styleUrls: ['./tab1.component.css']
})

以上只是举个例子。考虑一个有 10 个选项卡和许多子选项卡的应用程序。在那种情况下,第一个问题是我将不得不手动记下应用程序中所有这些选项卡的选择器-level.component.css。

另一个问题是,在不久的将来,一些新的开发人员可能会引入一个新的选项卡,但他的选项卡的内容不会像预期的那样增长或缩小,因为 he/she 甚至不知道他们必须添加他们的组件的选择器到应用程序级别-component.css。

是否有更普遍和推荐的方法来解决这个问题 Angular 4 这样:

  1. 我不必用所有这些 selectors
  2. 污染 app.component.css
  3. 以后的每个选项卡都会自动应用该样式。

我想 Decorators 可能是解决这个问题的正确方法,至少可以解决 #1。对于 #2,似乎新选项卡的开发人员至少必须将该装饰器应用到他的组件,因此 he/she 必须做一些工作,但它没有弄清楚所需的添加那么糟糕规则应用-component.css。我应该研究哪种装饰器?

注: tab1、tab2、tab1-subtab1、tab1-subtab2 不是 类。它们是由 Angular 路由器生成的组件。

一种方法是使用属性选择器 [attr=value],它有几个表达式,因此可以定位,即 类 以某个词开头或包含一个词。

[attr^=value]

表示属性名称为 attr 的元素,其值以值作为前缀(前面)。

[attr*=value] 

表示属性名称为 attr 的元素,其值在字符串中至少包含一次 value。

可以这样使用

:host ::ng-deep [class^='tab']          /*  start with 'tab'  */
{
  display: flex;
  flex-flow: column nowrap;
}

:host ::ng-deep [class*='-subtab']      /*  contain '-subtab'  */
{
  flex: 1 1 auto;
  flex-flow: row nowrap;
}

属性选择器也可以与你所谓的装饰器一起使用,即

:host ::ng-deep [flexcontainer]   /*  has the attribute `flexcontainer`  */
{
  display: flex;
  flex-flow: column nowrap;
}

:host ::ng-deep [flexitem]        /*  has the attribute `flexitem`  */
{
  flex: 1 1 auto;
}

答案描述中提到了两个主要限制条件:

  1. app.component.css 不应被每个组件的选择器污染
  2. 以后的每个标签都会自动应用该样式。

遵循应用程序级别的通用 CSS 规则可以兼顾两者。由于这些组件是由 Angular 路由器生成的。我们找到 router-outlet 并将 CSS 应用于它的直接兄弟(通过使用相邻的兄弟组合器),这是我们用于选项卡和子选项卡的组件。

:host ::ng-deep router-outlet + * { 
   display: flex; 
   flex: 1 1 auto; 
   flex-flow: column nowrap 
} 

新开发者无需为他们的新 tabs/subtabs 做任何额外的事情。