简体   繁体   English

从Angular 2中的子组件更新父组件属性

[英]Update parent component property from child component in Angular 2

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. 我正在使用@input从父组件接收属性,以激活子组件元素之一中的CSS类。

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. 我从父级接收的属性是一个类型的布尔数据,当我从子组件将其状态设置为false ,它在父级中不会更改。

Plunkr: https://plnkr.co/edit/58xuZ1uzvToPhPtOING2?p=preview Plunkr: https ://plnkr.co/edit/58xuZ1uzvToPhPtOING2 ? p = preview

app.ts 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 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 页眉/ 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. 请检查上面给出的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? @input是否适用于此方案? Please help me fix this. 请帮我解决这个问题。 (Please update the plunker). (请更新plunker)。

You need to use 2 way data-binding. 您需要使用双向数据绑定。

@Input() is one way data-binding. @Input()是一种数据绑定方式。 to enable 2 way data-binding you need to add an @Output() corresponding to the property, with a "Change" suffix 要启用双向数据绑定,您需要添加对应于该属性的@Output() ,并带有“更改”后缀

@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: 在父级中,您需要为该属性使用banana-in-a-box表示法:

[(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 看到plnkr

Another approach: use rxjs/BehaviorSubject to pass status between different components. 另一种方法:使用rxjs / BehaviorSubject在不同组件之间传递状态。
Here's the plunkr . 这是傻瓜
I name subject with a suffix 'Rxx', so the BehaviorSubject for searchStatus will be searchStatusRxx. 我用后缀“Rxx”命名主题,因此searchStatus的BehaviorSubject将是searchStatusRxx。

  1. initialize it in parent component like searchStatusRxx = new BehaviorSubject(false); 在父组件中初始化它,如searchStatusRxx = new BehaviorSubject(false); ,
  2. pass it to child component using @Input 使用@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. 在父级和子级中,您执行searchStatusRxx.next(value)以更改最新值。

Edited your code a little bit, it works and looks simplier imo. 编辑你的代码一点点,它的工作原理和看起来更简单的imo。 Tell me if you like it. 告诉我你是否喜欢它。

https://plnkr.co/edit/oJOjEZfAfx8iKZmzB3NY?p=preview 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 初始于子: searchStatus = false
  • In parent template, get the instance of child as #as or whatever name. 在父模板中,将child的实例作为#as或任何名称。
  • Change searchStatus in parent using #as.searchStatus and in child this.searchStatus . 使用#as.searchStatus和子this.searchStatus在父级中更改this.searchStatus

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM