I would like to pass color
from parent to child. Then in child component I wanted to access the element itselt to change the background color as follow this.element.nativeElement.style.backgroundColor === this.bgColor;
But there is no change.
child component: event-thumbnail.component.ts
parent component: events-list.component.ts
//event-thumbnail.component.ts
import { Component, ElementRef, Input, OnInit } from '@angular/core';
import { elementAt } from 'rxjs';
@Component({
selector: 'event-thumbnail',
template: `
<div >
<h2>{{ event.name }}</h2>
<div>Date: {{ event.date }}</div>
<div>Time: {{ event.time }}</div>
<div>Price: $ {{ event.price }}</div>
<div>
<span>Location: {{ event.location.address }}</span>
<span> </span>
<span>{{ event.location.city }}, {{ event.location.country }}</span>
</div>
</div>
`,
})
export class EventThumbnailComponent implements OnInit {
@Input() event: any = [];
@Input() bgColor: string = 'red';
constructor(public element: ElementRef) {
console.log(element.nativeElement);
}
ngOnInit(): void {
this.element.nativeElement.style.backgroundColor = this.bgColor;
console.log(this.element.nativeElement.style.backgroundColor); //
}
}
I am passing color
and event
from parent as below
//events-list.components.ts
import { Component } from '@angular/core';
@Component({
selector: 'events-list',
templateUrl: './events-list.component.html',
})
export class EventsListComponent {
color = 'black';
event = {
id: 1,
name: 'Angular Connect',
date: '9/26/2036',
time: '10:00 am',
price: 56,
imageUrl: '/assets/images/angularconnect-shiels.png',
location: {
address: '1057 DT',
city: 'London',
country: 'England',
},
};
}
//events-list.component.html
<div>
<h1>Upcoming Angular Events</h1>
<hr />
<event-thumbnail [bgColor]="color" [event]="event"></event-thumbnail>
</div>
CodePudding user response:
Use [ngStyle]
with the input you already have.
<div [ngStyle]="{ backgroundColor: bgColor }">
<!-- content here -->
</div>
It is an anti-pattern to put logic in a constructor, or to try and access anything using ElementRef
except in very specific circumstances.
CodePudding user response:
3 issues that i'm seeing with your code.
- in line
this.element.nativeElement.style.backgroundColor === this.bgColor;
you're not assigning the background color to the element, you should use "=" operator instead of "===" - your input of bgColor value won't be available in the constructor, only on OnInit which happens later
- your background won't be changed after the init because it's setting your background only when it's getting initialized.
i would solve it by using ngOnChanges() as following:
export class EventThumbnailComponent implements OnChanges {
@Input() event: any = [];
@Input() bgColor: string = 'red';
constructor(public element: ElementRef) {
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['bgColor']) {
this.element.nativeElement.style.backgroundColor === this.bgColor;
}
}
}
anyways, this is certainly not the best way to achieve what you're trying to, I suggest that you'll take a look on ngStyle directive.
CodePudding user response:
I agree with Gil's answer (https://stackoverflow.com/a/71705766/11022022), but I would try to do it with css only.
In the parent component's css:
.child-container {
background-color: #whatever;
}
In the child component's css:
:host {
background-color: inherit;
}
Also take a look at scss for more advanced options, such as variables: https://sass-lang.com/
CodePudding user response:
Input setter is your friend.
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-name-child',
template: '<h3>"{{name}}"</h3>'
})
export class NameChildComponent {
@Input()
set bgColor(name: string) {
this._bgColor = name;
}
private _bgColor: string = 'red';
constructor() {
}
}
https://angular.io/guide/component-interaction#intercept-input-property-changes-with-a-setter