61 votes

Mise à jour de la propriété du composant parent à partir du composant enfant dans Angular 2

J'utilise @input pour recevoir une propriété du composant parent afin d'activer une classe CSS dans l'un des éléments du composant enfant.

Je suis capable de recevoir la propriété du parent et aussi d'activer la classe. Mais cela ne fonctionne qu'une seule fois. La propriété que je reçois du parent est une donnée de type booléen et lorsque je lui donne le statut de false du composant enfant, il ne change pas dans le composant 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() { }
}

en-tête/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() {

  }
}

Veuillez vérifier les données ci-dessus. La fonction de recherche ouverte ne fonctionne qu'une seule fois. Après avoir fermé la recherche, elle ne se déclenche pas à nouveau.

Es @input est le cas d'utilisation approprié pour ce scénario ? Veuillez m'aider à résoudre ce problème. (S'il vous plaît mettre à jour le plunker).

111voto

n00dl3 Points 12707

Vous devez utiliser la liaison de données à deux voies.

@Input() est une liaison de données à sens unique. Pour activer la liaison de données dans les deux sens, vous devez ajouter une option @Output() correspondant à la propriété, avec un suffixe "Change".

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

lorsque vous voulez publier la modification apportée à votre propriété au parent, vous devez notifier le parent avec :

this.getSearchStatusChange.emit(newValue)

et dans le parent, vous devez utiliser la notation "banane dans une boîte" pour cette propriété :

[(getSearchStatus)]="myBoundProperty"

vous pouvez également vous lier à la propriété et déclencher un callback lorsqu'elle change dans l'enfant :

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

voir le plnkr

5voto

Timathon Points 711

Une autre approche : utiliser rxjs/BehaviorSubject pour transmettre le statut entre les différents composants.
Voici le plunkr .
Je nomme le sujet avec un suffixe 'Rxx', donc le BehaviorSubject pour searchStatus sera searchStatusRxx.

  1. l'initialiser dans le composant parent comme searchStatusRxx = new BehaviorSubject(false); ,
  2. le passer au composant enfant en utilisant @Input
  3. dans le modèle enfant, vous faites un pipe asynchrone.
  4. dans le parent et l'enfant, vous faites searchStatusRxx.next(value) pour modifier la dernière valeur.

3voto

kind user Points 20108

J'ai modifié un peu votre code, il fonctionne et semble plus simple. Dites-moi si vous l'aimez.

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

2voto

Timathon Points 711

Encore une autre façon. Plunkr . Ce que nous voulons, c'est une source unique de vérité. Nous pouvons mettre cela dans l'enfant cette fois.

  • Init dans l'enfant : searchStatus = false
  • Dans le modèle parent, récupérez l'instance de l'enfant en tant que #as ou tout autre nom.
  • Modifier le statut de recherche dans le parent en utilisant #as.searchStatus et en enfant this.searchStatus .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X