web-dev-qa-db-fra.com

Angular 2 - Appliquer un style conditionnel à l'élément HTML enfant d'une directive

J'essaie d'appliquer une classe à un élément HTML en fonction d'un événement click. Cela fonctionne correctement lorsque vous définissez la propriété de classe pour le sélecteur du composant enfant à partir du modèle du composant parent, comme indiqué par l'extrait suivant du composant parent:

[class.bordered]='isSelected(item)'

Cela définira correctement le style lorsque cet élément est cliqué. Cependant, je veux définir la classe d'un élément HTML interne dans le composant enfant en fonction du même type d'événement click, voici la cible souhaitée pour le style du composant enfant:

template: `
  <div class="This is where I really want to apply the style">  
    {{ item.val }}
  </div>
`

Y at-il un moyen de faire cela qui est facilement pris en charge? Ou est-ce considéré comme une mauvaise pratique et je devrais concevoir mes composants pour éviter ce genre de situation de style conditionnel?

Code complet:

@Component({
  selector: 'parent-component',
  directives: [ChildComponent],
  template: `
    <child-component
      *ngFor='#item of items'
      [item]='item'
      (click)='clicked(item)'
      [class.bordered]='isSelected(item)'>
    </child-component>
  `
})
export class ParentComponent {
  items: Item[];
  currentItem: item;

  constructor(private i: ItemService) {
    this.items = i.items;
  }

  clicked(item: Item): void {
    this.currentItem = item;
  }

  isSelected(item: Items): boolean {
    if (!item || !this.currentItem) {
      return false;
    }
    return item.val === this.currentItem.val;
  }
}


@Component({
  selector: 'child-component',
  inputs: ['item'],
  template: `
    <div class="This is where I really want to apply the style">  
      {{ item.val }}
    </div>
  `
})
export class ChildComponent {}
6
Chris

J'ai trouvé un meilleur moyen de résoudre ce problème en faisant bon usage des fonctionnalités Angular2.

Plus précisément, au lieu de faire de la supercherie avec: Host et les fonctionnalités CSS, vous pouvez simplement transmettre une variable au composant enfant en modifiant:

[class.bordered]='isSelected(item)'

étant défini dans l'élément de la classe enfant le changer en

[isBordered]='isSelected(item)'

Ensuite, sur la div à laquelle vous souhaitez appliquer la classe bordée dans le modèle du composant enfant, ajoutez simplement:

[ngClass]='{bordered: isBordered}'

Voici le code complet avec le changement:

@Component({
  selector: 'parent-component',
  directives: [ChildComponent],
  template: `
    <child-component
      *ngFor='#item of items'
      [item]='item'
      (click)='clicked(item)'
      [isBordered]='isSelected(item)'>
    </child-component>
  `
})
export class ParentComponent {
  items: Item[];
  currentItem: item;

  constructor(private i: ItemService) {
    this.items = i.items;
  }

  clicked(item: Item): void {
    this.currentItem = item;
  }

  isSelected(item: Items): boolean {
    if (!item || !this.currentItem) {
      return false;
    }
    return item.val === this.currentItem.val;
  }
}


@Component({
  selector: 'child-component',
  inputs: ['item'],
  template: `
    <div [ngClass]='{bordered: isBordered}'>
      {{ item.val }}
    </div>
  `
})
export class ChildComponent {}
4
Chris

Ajouter un style au child-component

@Component({
  selector: 'child-component',
  inputs: ['item'],
  template: `
    <div class="This is where I really want to apply the style">  
      {{ item.val }}
    </div>
  `,
  styles: [`
    :Host(.bordered) > div {
    // if this selector doesn't work use instead
    // child-component.bordered > div {
      border: 3px solid red;
    }
  `],
})
export class ChildComponent {}
4
Günter Zöchbauer

Quelque chose comme ça marche très bien pour moi: 

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

@Component({
  selector: 'my-app',
  styleUrls: [ './app.component.css' ],
  template: `
  <button 
    (click)='buttonClick1()' 
    [disabled] = "btnDisabled"
    [ngStyle]="{'color': (btnDisabled)? 'gray': 'black'}">
    {{btnText}}
  </button>`
})
export class AppComponent  {
  name = 'Angular';
  btnText = 'Click me';
  btnDisabled = false;
  buttonClick1() {
    this.btnDisabled = true;
    this.btnText = 'you clicked me';
    setTimeout(() => {
      this.btnText = 'click me again';
      this.btnDisabled = false
      }, 5000);
  }
}

Voici un exemple de travail:
https://stackblitz.com/edit/example-conditional-disable-button?file=src%2Fapp%2Fapp.component.html

0
BraveNewMath