【问题标题】:@Output communication between child and parent. Angular 2(5)@Output 孩子和父母之间的通信。角 2(5)
【发布时间】:2017-11-14 17:34:19
【问题描述】:

我正在尝试学习 Angular 2,并尝试在父组件中设置一个变量,其中包含来自我的子组件的数据。基本上我的父视图中有一个子标题,我希望标题和一些 HTML 根据加载的子项进行更改。

父组件:

import { Component, OnInit, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class ParentComponent {
  childDetails: {title: String, helperBar: String};

  onChildLoaded(childData: {
    childTitle: string,
    childHelperBar: string
  }) {
    this.childDetails ={
      title: childData.childTitle,
      helperBar: childData.childHelperBar
    };
    console.log (childDetails);
  }
}

子组件:

import { Component, OnInit, ViewEncapsulation, Output, EventEmitter } 
from '@angular/core';

@Component({
  selector: 'app-first-child',
  templateUrl: './first-child.component.html',
  styleUrls: ['./first-child.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class FirstChildComponent implements OnInit {
  @Output() childLoaded = new EventEmitter<{childTitle: string, 
childHelperBar: string}>();

  constructor() { }

  ngOnInit() {
    this.childLoaded.emit({
      childTitle: 'Dashboard',
      childHelperBar: '<div class="test"><button>Dash Button</button>
</div>'
    });
  }

}

最后是我的父级 HTML:

<div class="subheader">
  <h1>{{ childDetails.title }}</h1>
  {{ childDetails.helperBar }}
</div>
<nav class="sidebar">

</nav>

<main role="main" class="">
  <router-outlet (childLoaded)="onChildLoaded($event)"></router-outlet>
</main>

在我的一生中,我无法让这种方法发挥作用,也无法确定我哪里出错了。我总是可以把副标题放在我的孩子身上,但我不喜欢重复代码这么多次的想法,这会使我的布局更难实现。

【问题讨论】:

  • 在路由器插座中加载的组件与包装路由器的组件之间没有父子关系。您应该使用其他方法,例如共享服务。
  • 因此,例如,如果 被替换为 这种方法会奏效吗?显然不适合我,但只是为了确保我得到它。无论如何感谢您的意见,将继续提供服务,干杯;)
  • @Cheekumz,最好的方法是使用服务,但如果你想使用你正在寻找的路由器插座是(激活)事件,请查看stackoverflow.com/questions/39255311/…,干杯!!

标签: javascript angular angular2-routing


【解决方案1】:

最好的办法是利用服务和observable,这样每当子组件发生变化时,新的数据就会立即反映在父组件中。

在您的 service.ts 中,

import { Subject } from 'rxjs/Subject'
import { Observable } from 'rxjs/Rx';

@Injectable()
export class myService {

  private pageName = new Subject<string>();

  pageNameChange$ = this.pageName.asObservable();
  changedComponentName(option:string){
        this.pageName.next(option);
  }
}

在您的子组件中,

子组件 1

public ngOnInit() {
  this.myService.changedComponentName('child1');
}

子组件 2

public ngOnInit() {
   this.myService.changedComponentName('child2');
}

等等..

现在,要在父组件中获取更改后的组件名称,

父组件.ts

import { Subscription } from 'rxjs';

export class parentComponent {

    private subscription:Subscription;

    constructor(private myService:myService){

        this.myService.pageNameChange$.subscribe( /* get called on every child page changes*/
         newPageName => {

        console.log(newPageName); // you get your passed component name ( child1 / child2 /etc.. here in the 'newPageName' variable
    });
  }
}

【讨论】:

  • 非常感谢。
【解决方案2】:

你得到了吗? $event 在你的父方法中?

如果是,那么你为什么在父类方法中使用let childDetails ={}。相反,您应该使用this.childDetails={}

onChildLoaded($event){
 this.childDetails ={ title: $event.childTitle, helperBar: $event.childHelperBar }; 
console.log (childDetails); 
}

和父 html 应该是

<div class="subheader"> <h1>{{ childDetails.title }}</h1> {{ childDetails.helperBar }} </div> 
<nav class="sidebar"> </nav> 
<main role="main" class="">
 <app-first-child (childLoaded)="onChildLoaded($event)"></app-first-child> </main>

如果你不想使用&lt;app-first-child/&gt;,那么你应该使用共享服务

【讨论】:

  • 对不起,这实际上是一个错误,我一直在使用这个。在我的代码中。已相应地更新了我的问题。 :)
猜你喜欢
  • 2011-02-20
  • 2017-08-26
  • 2011-02-21
  • 2021-01-13
  • 1970-01-01
  • 2017-07-01
  • 2020-01-29
  • 2018-02-26
  • 1970-01-01
相关资源
最近更新 更多