IT TIP

Angular 2의 자식 구성 요소에서 부모 구성 요소 속성 업데이트

itqueen 2020. 12. 29. 08:11
반응형

Angular 2의 자식 구성 요소에서 부모 구성 요소 속성 업데이트


@input자식 구성 요소의 요소 중 하나에서 CSS 클래스를 활성화하기 위해 부모 구성 요소에서 속성을받는 데 사용 하고 있습니다.

부모로부터 속성을 받고 클래스를 활성화 할 수도 있습니다. 그러나 이것은 한 번만 작동합니다. 부모로부터받는 속성은 부울 데이터 형식이며 false자식 구성 요소에서 상태를 설정하면 부모에서 변경되지 않습니다.

플 런커 : https://plnkr.co/edit/58xuZ1uzvToPhPtOING2?p=preview

app.ts

import {Component, NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { HeaderComponent } from './header';
import { SearchComponent } from './header/search';

@Component({
  selector: 'my-app',
  template: `
    <app-header></app-header>
  `,
})
export class App {
  name:string;
  constructor() {
  }
}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App, HeaderComponent, SearchComponent ],
  bootstrap: [ App ]
})
export class AppModule {}

header.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-header',
  template: `<header>
              <app-search [getSearchStatus]="isSearchActive"></app-search>
              <button (click)="handleSearch()">Open Search</button>
            </header>`
})
export class HeaderComponent implements OnInit {
  isSearchActive = false;

  handleSearch() {
    this.isSearchActive = true
    console.log(this.isSearchActive)
  }

  constructor() { }
  ngOnInit() { }
}

header / search.ts

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-search',
  template: `<div id="search" [class.toggled]="getSearchStatus">
              search 
              <button  (click)="getSearchStatus = false" class="close">Close Search</button>
            </div>`
})
export class SearchComponent implements OnInit {
  @Input() getSearchStatus: boolean;

  constructor() { }

  ngOnInit() {

  }
}

위의 플 런커를 확인하십시오. 열린 검색 기능은 한 번만 작동합니다. 검색을 닫은 후 다시 트리거되지 않습니다.

Is @input is the proper use case for this scenario? Please help me fix this. (Please update the plunker).


You need to use 2 way data-binding.

@Input() is one way data-binding. to enable 2 way data-binding you need to add an @Output() corresponding to the property, with a "Change" suffix

@Input() getSearchStatus: boolean;
@Output() getSearchStatusChange = new EventEmitter<boolean>();

when you want to publish the change made to your property to the parent, you need to notify the parent with:

this.getSearchStatusChange.emit(newValue)

and in the parent you need to use the banana-in-a-box notation for that property:

[(getSearchStatus)]="myBoundProperty"

you can also bind to the property and trigger a callback when it changes in child:

[getSearchStatus]="myBoundProperty" (getSearchStatusChange)="myCrazyCallback($event)"

see the plnkr


Another approach: use rxjs/BehaviorSubject to pass status between different components.
Here's the plunkr.
I name subject with a suffix 'Rxx', so the BehaviorSubject for searchStatus will be searchStatusRxx.

  1. initialize it in parent component like searchStatusRxx = new BehaviorSubject(false);,
  2. pass it to child component using @Input
  3. in child template, you do async pipe.
  4. in both parent and child, you do searchStatusRxx.next(value) to change the latest value.

Edited your code a little bit, it works and looks simplier imo. Tell me if you like it.

https://plnkr.co/edit/oJOjEZfAfx8iKZmzB3NY?p=preview


Yet another way. Plunkr. What we want is a single source of truth. We can put that in child this time.

  • Init in child: searchStatus = false
  • In parent template, get the instance of child as #as or whatever name.
  • Change searchStatus in parent using #as.searchStatus and in child this.searchStatus.

ReferenceURL : https://stackoverflow.com/questions/41464871/update-parent-component-property-from-child-component-in-angular-2

반응형