Update parent component property from child component in Angular 2

白昼怎懂夜的黑 提交于 2019-11-26 12:56:02

问题


I\'m using @input to receive a property from parent component in order to activate a CSS class in one of child component\'s element.

I\'m able to receive the property from parent and also activate the class. But this works only once. The property i\'m receiving from parent is a boolean data typed and when I set the status of it to false from child component, it does not change in parent.

Plunkr: 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() {

  }
}

Please check the above given plunker. The open search function works only once. After closing the search, it does not trigger again.

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


回答1:


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




回答2:


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.



回答3:


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




回答4:


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.


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!