从 Angular 中的 child 组件更新 parent 组件 属性 2

Update parent component property from child component in Angular 2

我正在使用 @input 从 parent 组件接收 属性 以便在 [=47] 之一中激活 CSS class =] 组件的元素。

我能够从 parent 接收 属性 并激活 class。但这只有效一次。我从 parent 收到的 属性 是一个布尔型数据,当我从 child 组件将它的状态设置为 false 时,它在 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() {

  }
}

请检查上面给出的plunker。打开搜索功能只能使用一次。关闭搜索后,不再触发。

@input 是该场景的正确用例吗?请帮我解决这个问题。 (请更新 plunker)。

您需要使用 2 种方式的数据绑定。

@Input() 是一种数据绑定方式。 要启用 2 路数据绑定,您需要添加一个 @Output() 对应于 属性,并带有 "Change" 后缀

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

当您想将对 属性 所做的更改发布给家长时,您需要通过以下方式通知家长:

this.getSearchStatusChange.emit(newValue)

并且在父级中,您需要为此使用盒装香蕉符号 属性:

[(getSearchStatus)]="myBoundProperty"

您还可以绑定到 属性 并在其更改时触发回调:

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

查看 plnkr

稍微编辑一下您的代码,它可以工作并且看起来更简单 imo。喜欢就告诉我吧

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

另一种方法:使用rxjs/BehaviorSubject在不同组件之间传递状态。
这是 plunkr.
我用后缀 'Rxx' 命名主题,因此 searchStatus 的 BehaviorSubject 将是 searchStatusRxx。

  1. 在父组件中初始化它 searchStatusRxx = new BehaviorSubject(false);,
  2. 使用@Input 将其传递给子组件
  3. 在子模板中,你做异步管道。
  4. 在父项和子项中,您都searchStatusRxx.next(value)更改最新值。

还有一种方式。 Plunkr。我们想要的是单一的事实来源。这次我们可以把它放在 child 中。

  • 在 child 中初始化:searchStatus = false
  • 在 parent 模板中,获取 child 的实例作为 #as 或任何名称。
  • 使用 #as.searchStatus 和 child this.searchStatus.
  • 更改 parent 中的搜索状态