Reputation: 2485
I want to click any component of type CardComponent
and then change variable currentState
for others. But it seems like currentState
cant be changed - it can only be changed for clicked element when using this
.
let numInstances = 0;
@Component({
selector: 'app-card',
templateUrl: './card.component.html',
styleUrls: ['./card.component.scss'],
animations: [
trigger('change', [
state('show', style({
opacity: 1
})),
state('hide', style({
opacity: 0
})),
transition('show=>hide', animate('150ms')),
transition('hide=>show', animate('150ms'))
])
]
})
export class CardComponent {
currentState = 'show';
private instanceId: number;
constructor() {
this.instanceId = numInstances++;
}
get id() {
return 'card_' + this.instanceId;
}
public toggle(): void {
const items = document.getElementsByClassName('card-container'); // other items
for (const item of items as any) {
if (item.id !== this.id) {
item.currentState = 'hide'; // current state is not changing
} else {
this.currentState = 'show'; // when using this, state is changing
}
}
}
}
How can I change the currentState
for other items ?
Upvotes: 0
Views: 37
Reputation: 7875
on angular, most of the time, is bad idea to try to manipulate your DOM and access by vanillajs.
I recommand you to adapt your code by using the design recommanded by Angular Core team.
Container and UI component
that means you have components which represent your user interface. That components only use Input/Output to interact with rest of your application. That will help you to make your UI generic and easy to change.
They can looks like following :
@Component({
selector: 'hello',
template: `<h1 (click)="onClickHandler()">{{ isActive && 'Hello' || 'Bye' }} {{name}}!</h1>`,
styles: [`h1 { font-family: Lato; }`]
})
export class HelloComponent {
@Input() name: string;
@Input() isActive: boolean = false;
@Output() onClick: EventEmitter<string> = new EventEmitter();
onClickHandler() {
this.onClick.emit(this.name);
}
}
Here in have basic UI component which can receive :
And emit :
Then you have Container components, role of this component to make the bridge between your data storage, business logic, api request... And your UI.
It will looks like following :
export class AppComponent {
constructor(public storeService: StoreService) {}
isActive(name: string): Observable<boolean> {
return this.storeService.isActive(name);
}
setCurrent(name: string) {
this.storeService.setCurrent(name);
}
}
Then you have your store and business logic, most of the time inside Service
@Injectable()
export class StoreService {
private currentActive$ = new BehaviorSubject('Bob');
isActive(name: string): Observable<boolean> {
return this.currentActive$.pipe(map((current) => current === name));
}
setCurrent(name: string) {
this.currentActive$.next(name);
}
}
Here you have one observable currentActive$
which will keep track of all change from your toggle.
You can update the current active by calling setCurrent
method.
Now what your UI want is to know if him are the current active or not. For that you can use isActive(name: string): Observable<boolean>
.
It simply take the global active stream, and map it to have stream of true
or false
Upvotes: 1