MorKadosh MorKadosh - 3 months ago 50
TypeScript Question

Angular2 add class to parent component on child event execution

I am working on a project using Angular2 and until now find it awesome!
But on the other hand, I find some pretty simple tasks frustrating.

Well, what I am trying to do is pretty simple:

In my app I have a header component (reusable through all app) and a search-bar component.

The Header component looks like that:

import {Component, Input} from '@angular/core';
import {IONIC_DIRECTIVES} from 'ionic-angular';
import {SearchBar} from './../../component/search/search.component';

@Component({
selector : 'med-header',
templateUrl : 'build/component/header/header.component.html',
directives : [IONIC_DIRECTIVES, SearchBar]
})

export class Header {
@Input()
showLogo : number;
/**
* constructor
*/
constructor(){
}
};


And the template:

<ion-header>
<ion-navbar>
<ion-title>
<img *ngIf="showLogo" src="build/assets/images/logo.png" id="main-logo" />
</ion-title>
<div id="search-box"><med-search></med-search></div>
</ion-navbar>
</ion-header>


And the search bar component:

import {Component} from '@angular/core';
import {IONIC_DIRECTIVES} from 'ionic-angular';
import {NavController} from 'ionic-angular';

@Component({
selector : 'med-search',
templateUrl : 'build/component/search/search.component.html',
directives : [IONIC_DIRECTIVES]
})

export class SearchBar {
private focused : boolean;
private keyword : any;
/**
* constructor
*/
constructor(private navCtrl : NavController){
}

animateComponent(){
this.focused = true;
}
};


And search bar template:

<ion-searchbar (ionInput)="getItems($event)" [(ngModel)]="keyword" [ngClass]="{'focused' : focused}" (ionFocus)="animateComponent()"></ion-searchbar>


I am trying to achieve this simple task: when the user focuses on the search bar, animate the search-bar's container (for example, increase it's width etc.)

Well, if it was jQuery, I would achieve this task pretty easily.
In angualr2 it seems a bit complicated.

I thought maybe using the :host selector I could achieve my goal, but found out that I am not able to know if the search-bar is focused or not.
I also thought about EventEmitter, but it sounds like an overkill and it did not work as expected.
Is there anyway to apply a class to a parent, depanding on it's child components?

Does anyone know how to do that?

Thanks.

Answer

Well, I finally resolved the issue using the @Output decorator.

I added a changedFocus property to the searchBar component:

@Output() changedFocus : EventEmitter<boolean> = new EventEmitter<boolean>();

And as well added the event handlers in the searchbar:

  /**
   * executed when the form is focused
   */
  focus(){
    this.changedFocus.emit(true);
  }

  /**
   * executed when the form is blured
   */
  blur(){
    this.changedFocus.emit(false);
  }

Then, in the Header component I added a focused property:

private focused : boolean;

And a changeFocus method:

  /**
   * change element focus
   */
  changeFocus(){
    this.focused = !this.focused;
  }

Which is executed everytime the focus state changes on the child component. That gave me the wanted result.

Comments