简体   繁体   English

如何根据组件内容的可见性,有条件地将 styles 应用到组件标签上?

[英]How to conditionally apply styles on the component tag based on the visibility of component contents?

Let's say I have a component like this which contains logic to show or hide the contents inside the component:假设我有一个像这样的组件,其中包含显示或隐藏组件内内容的逻辑:

@Component({
  selector: 'hello',
  template: `<div *ngIf="visible"> <h1>Hello {{name}}!</h1></div>`,
  styles: [`h1 { font-family: Lato; } div { border: 1px solid blue }`]
})
export class HelloComponent  {
  @Input() name: string;
  visible: boolean;
  ngOnInit() {
    this.visible = this.name === "Stranger"
  }
}

And I use it like this in another component:我在另一个组件中这样使用它:

<div class="container">
  <hello class='hello-class' name="Stranger"></hello>

  <!-- This will not be visible -->
  <hello class='hello-class' name="Not stranger"></hello>
</div>

And I apply some styles to the hello components like this:我将一些 styles 应用于hello组件,如下所示:

.hello-class {
  display: block;
  margin-bottom: 80px;
}

The 2nd use of hello component will be invisible because of the conditions in the component.由于组件中的条件,第二次使用hello组件将是不可见的。 But even if the component is invisible the styles I added to hello-class gets applied to the component.但即使组件不可见,我添加到hello-class的 styles 也会应用于组件。

I cannot move the condition to show/hide the component to the parent.我无法将条件移动以向父级显示/隐藏组件。 So I cannot do an *ngIf before the component.所以我不能在组件之前做一个*ngIf

Is there any way I can apply this style only if the component is visible?只有当组件可见时,我才能应用这种样式吗?

Here's a link to stackblitz illustrating the issue: https://stackblitz.com/edit/angular-ivy-mfrb7j这是说明问题的 stackblitz 的链接: https://stackblitz.com/edit/angular-ivy-mfrb7j

Since there are no children, you can do this with a css selector:由于没有子节点,您可以使用 css 选择器执行此操作:

.hello-class:not(:empty) {
  display: block;
  margin-bottom: 80px;
}

By using :not(:empty) it checks if the element (the host element for the component) has children.通过使用:not(:empty)它检查元素(组件的宿主元素)是否有子元素。 If it doesn't have children, then the style won't apply.如果它没有子项,则该样式将不适用。

https://developer.mozilla.org/en-US/docs/Web/CSS/:empty https://developer.mozilla.org/en-US/docs/Web/CSS/:empty

Conditional styling with ngClass would work in this situation also. ngClass 的条件样式也适用于这种情况。

So in your HTML you would put:所以在你的 HTML 你会放:

<div class="container">
  <hello [ngClass]="{'hello-class': visible}" name="Stranger"></hello>

  <!-- This will not be visible -->
  <hello [ngClass]="{'hello-class': visible}" name="Not stranger"></hello>
</div>

So when visible = true, it will apply 'hello-class' styling.所以当 visible = true 时,它将应用 'hello-class' 样式。


Expanded answer below下面的扩展答案

Option 1:选项1:

Custom Property Binding & ngClass自定义属性绑定 & ngClass

hello.component.ts - make the "visible" property bindable in the parent component: hello.component.ts - 使父组件中的“可见”属性可绑定:

@Component({
  selector: 'hello',
  template: `<div *ngIf="visible"> <h1>Hello {{name}}!</h1></div>`,
  styles: [`h1 { font-family: Lato; } div { border: 1px solid blue }`]
})
export class HelloComponent  {
  @Input() name: string;
  @Input() visible: boolean;
  ngOnInit() {
    this.visible = this.name === "Stranger"
  }
}

parent.component.html - bind to the "visible" property of hello component and apply conditional styling with ngClass: parent.component.html - 绑定到 hello 组件的“可见”属性并使用 ngClass 应用条件样式:

<div class="container">
  <hello [visible]="visibility" [ngClass]="{'hello-class': visibility}" name="Stranger"></hello>

  <!-- This will not be visible -->
  <hello [visible]="visibility" [ngClass]="{'hello-class': visibility}" name="Not stranger"></hello>
</div>

parent.component.ts - add the local property "visibility": parent.component.ts - 添加本地属性“可见性”:

visibility: boolean;

Option 2选项 2

Local Reference & ngClass本地参考 & ngClass

Alternatively, if you cannot add anything to the parent.component.ts file, you can do it all in html.或者,如果您无法向 parent.component.ts 文件添加任何内容,您可以在 html 中完成所有操作。 You don't need to add the @Input() decorator to your hello.component.ts file for this, either.为此,您也不需要将@Input()装饰器添加到您的 hello.component.ts 文件中。 Seems a bit rough, but it works.看起来有点粗糙,但它确实有效。

parent.component.html - use local reference to trigger the conditions for ngClass: parent.component.html - 使用本地引用来触发 ngClass 的条件:

    <div class="container">
  <hello #a [ngClass]="{'hello-class': a.visible}" name="Stranger"></hello>

  <hello #b [ngClass]="{'hello-class': b.visible}" name="Not stranger"></hello>
</div>

Append the name inputs for compponent to variables. Append 变量的组件名称输入。

public helloNames = [ 'Stranger', 'Not stranger'];

Then in component, do as below.然后在组件中,执行以下操作。

<div class="container">
  <hello class='hello-class' *ngIf="helloNames[0] == 'Stranger'" name="helloNames[0]"></hello>

  <!-- This will not be visible -->
  <hello class='hello-class' *ngIf="helloNames[1] == 'Stranger'" name="helloNames[1]"></hello>
</div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM