2

I have a component that in which I'd like to pass certain data to the child component in ngFor through attribute. And based on attribute I'd like to ultimately style those child-components.

Code

testimonials.component.html - (Parent component)

<ng-template ngFor let-person="$implicit" [ngForOf]="peopleAsPreviousCurrentAndNextTriplets" let-i=index let-last=last>
    <app-card
           [prevCard]      ="last ? person.previous : null"
           [currentCard]   ="last ? person.current : null"
           [nextCard]      ="last ? person.next : null"
    ></app-card>
</ng-template>

card.component.ts - (Child component)

import {Component, Input, ViewChild} from '@angular/core';
import {Person} from '../testimonials/person';

@Component({
  selector: 'app-card',
  templateUrl: './card.component.html',
  styleUrls: ['./card.component.scss']
})
export class CardComponent {
  @Input() decrement:     Number;
  @Input() defaultDiff:   Number;
  @Input() currentCard:   Person;
  @Input() prevCard:      Person;
  @Input() nextCard:      Person;
  @ViewChild('card')      card;

  constructor() { }
}

And I would like to style <app-card> with a [currentCard] attribute.

child.component.sass

:host {
  &[currentCard] {
    .testimonials__card-container {
      background-color: black;
    }
  }
}

Not sure why the above style is not being applied.

Please help.

Thanks

EDIT

Here's to visualise my tacked cards:

enter image description here

4
  • 1
    [currentCard] is a binding, it doesn't actually apply that attribute. Try putting a class on the element conditionally instead. Commented Aug 15, 2017 at 16:38
  • Your question was my daily dose of SO. Thank you for this. Commented Aug 15, 2017 at 16:42
  • Lol, Im not sure if should be happy about that. Apologies if I caused you any annoyance @Moshe Commented Aug 16, 2017 at 9:08
  • 1
    I learned something new* :) Commented Aug 16, 2017 at 13:51

1 Answer 1

4

Don't mix up html attributes and Angular bindings. What would work is something like this:

in the parent view:

   <app-card [class.currentcard]= "last"
               [prevCard]      ="last ? person.previous : null"
               [currentCard]   ="last ? person.current : null"
               [nextCard]      ="last ? person.next : null">
    </app-card>

and in the stylesheet of the child:

:host(.currentcard) {
   background-color: black;
}
Sign up to request clarification or add additional context in comments.

14 Comments

OMG, I really apologise for not getting back to you soon. And yes this was very helpful, and I really appreciate it. Just one question though. I come from Polymerjs background and the way we do it is style it based on attribute you pass. And then target it within the host. Heres a similar question I asked earlier. But it didnt work at the end. I misundertood it: stackoverflow.com/questions/45691491/…
Would it be possible to do it angular4 though? I'd prefer not to add class at all in the first place. And just style it within host
Well not exactly, so think of this as a gallery (stacked items galler) - where the current one will be at the top of the stack, and the [prevCard] will be behind the current card but on the left, and the [rightCard] will on behind the currentCard but on the right. And there will be two buttons, when I click next, the current card becomes the prevCard, and the nextCard becomes the currentCard. Do u get the idea?
So basiclaly, I thought it would be trivial having a class for each one. Why not just deal with them durectly in the host. without classes
Well, JBNizet's answer doesn't actually work. I tried doing what he suggested. But didn't work.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.