Pass change state from parent to particular child from *ngFor


#1

Hi everyone!

What I’m trying to do is to listen to scroll event, check if child element is in viewport (I’ve got all children offsetTop values for this purpose) and change its state in order to see fade in animation. The problem is: there are plenty of child elements generated with *ngFor loop and I can’t figure out how to pass state change to exact child.

I’m listening to scroll events using this function:

ngAfterViewInit() {
 this.content.ionScroll.subscribe(event => this.detectElementVisibility(event));
}

For now I’m just testing this function, so I am trying to change first child state if scrollOffset is higher than 25:

detectElementVisibility(e) {
 if (e.scrollTop > 25) {
  this.items[0].state = 'inactive'; //this.items is my array of fetched items from server
 }
}

In my parent html I am trying to pass this state to child:

<ion-list>
    <news-item *ngFor='let item of items' [state]='state' [item]='item'></news-item>
</ion-list>

And catch it in child component:

export class NewsItem {
 @Input state: any;
}

Any ideas on how to do it?


#2

I don’t quite understand your question, so if this doesn’t help, I apologize. But I think this might help: You can set *ngFor = 'let item of items; let i of index' and then give each of your children the template id #i. So then you can refer to each child uniquely, and check if child “5” has a particular property. Also, you can refer to the first with first, and the last with last.


#3

Sorry for not being more specific) So, the problem is when I am trying to change element’s state, nothing changes. I’ve tried your advice, but still nothing happens. Maybe, the “state” attribute is not attached to DOM element, so I can’t change it in such a way


#4

What do you mean by a state? It isn’t a property of HTMLElement.


#5

Exactly! It isn’t. By a state I mean state needed for creating animation inside component. Something like this:

@Component({
    selector: 'news-item',
    templateUrl: 'news-item.html',

    animations: [
        trigger("elementState", [
            state("inactive", style({
                opacity: 0
            })),
            state("active", style({
                opacity: 1
            })),
            transition("inactive => active", animate("4000ms ease-in")),
            transition("active => inactive", animate("4000ms ease-out")),
        ])
    ]
})

So, I need somehow to pass state change to particular component item (its particular duplicate, let’s say, 5th ) from parent component.


#6

Can you handle that in CSS, like an advanced version of this Plunkr? Use [ngClass] or [ngStyle] with index to assign different CSS to each element inside your ngFor?


#7

Awesome idea with just adding items one by one!!! As simple as it should be!!! No more headaches, you brought peace to my mind, thank you