Обновить свойство родительского компонента из дочернего компонента в Angular 2

Я использую @input получить свойство от родительского компонента, чтобы активировать класс CSS в одном из элементов дочернего компонента.

Я могу получить свойство от родителя, а также активировать класс. Но это работает только один раз. Свойство, которое я получаю от родителя, типизируется логическими данными, и когда я устанавливаю для него статус false от дочернего компонента, он не изменяется в родительском.

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() { }
}

заголовок /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() {

  }
}

Пожалуйста, проверьте указанный выше поршень. Функция открытого поиска работает только один раз. После закрытия поиска он не запускается снова.

Является @input правильный вариант использования для этого сценария? Пожалуйста, помогите мне исправить это. (Пожалуйста, обновите поршень).

4 ответа

Решение

Вам нужно использовать 2 способа привязки данных.

@Input() это один из способов привязки данных. Для включения двухсторонней привязки данных необходимо добавить @Output() соответствует свойству с суффиксом "Изменить"

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

если вы хотите опубликовать изменения, внесенные в вашу собственность, родителю, вы должны уведомить об этом родителя с помощью:

this.getSearchStatusChange.emit(newValue)

и в родителе вы должны использовать нотацию banana-in-a-box для этого свойства:

[(getSearchStatus)]="myBoundProperty"

Вы также можете привязать свойство и вызвать обратный вызов при его изменении в child:

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

посмотреть плнкр

Другой подход: используйте rxjs/BehaviorSubject для передачи статуса между различными компонентами.
Вот этот планкр.
Я называю тему суффиксом 'Rxx', поэтому объектом поведения для searchStatus будет searchStatusRxx.

  1. инициализировать его в родительском компоненте, как searchStatusRxx = new BehaviorSubject(false);,
  2. передать его дочернему компоненту с помощью @Input
  3. в дочернем шаблоне вы делаете асинхронный канал.
  4. как в родительском, так и в детском searchStatusRxx.next(value) изменить последнее значение.

Немного отредактировал ваш код, он работает и выглядит проще imo. Скажи мне, если тебе нравится.

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

Еще один способ. Плункр. То, что мы хотим, это единственный источник правды. Мы можем поместить это в ребенка на этот раз.

  • Посвящение в ребенка: searchStatus = false
  • В родительском шаблоне получите экземпляр child как #as или как там ни зовут.
  • Изменить searchStatus в родительском с помощью #as.searchStatus и у ребенка this.searchStatus,
Другие вопросы по тегам