首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >子组件到父组件之间的通信,没有嵌套在角模板中的子组件(角2+)

子组件到父组件之间的通信,没有嵌套在角模板中的子组件(角2+)
EN

Stack Overflow用户
提问于 2017-03-07 16:46:57
回答 3查看 4K关注 0票数 2

每个答复的帖子和每个教程都显示,如果父组件正在侦听,则可以使用EventEmitter()与其子组件与其父组件对话;但是,只有当子组件是父模板的一部分时,才能使用该子组件;否则,只能由应用程序的根组件获取发出消息。

下面是一个简单的结构(在<ng-content></ng-content>上使用radio-group来转换子结构):

代码语言:javascript
复制
<radio-group>
  <radio></radio>
  <radio></radio>
  <radio></radio>
</radio-group>

当检查自定义无线电组件时,它应该会发出一个事件--这个事件很好用。但是,自定义无线电组即使在监听,也不会听到事件,因为在这个实现中,它的子部分不是它的模板。

我不明白角材料2收音机是如何做到这一点的,但是对于那些很好地理解角度2的人来说,这将是一个很好的参考。

单击角材料2无线电演示的“示例”选项卡,查看我试图完成的任务,并单击“源”按钮,查看与我试图复制的结构相同的结构。

同样,我不是试图复制和粘贴它们的实现,而是试图让子组件在子组件不是父模板的一部分时将事件传递给父组件。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-03-07 18:00:09

如果您转到那个柱塞,您将看到它们具有以下结构:

代码语言:javascript
复制
<radio-ng-model-example>
    <md-radio-group class="example-radio-group" [(ngModel)]="favoriteSeason">
        <md-radio-button class="example-radio-button" *ngFor="let season of seasons" [value]="season">
            {{season}}
        </md-radio-button>
    </md-radio-group>
    <div class="example-selected-value">Your favorite season is: {{favoriteSeason}}</div>
</radio-ng-model-example>

radio-ng-model-example是根组件。因此,他们使用EventEmittermd-radio-buttonmd-radio-group之间进行通信,使用ngModelmd-radio-groupradio-ng-model-example之间进行通信。

票数 1
EN

Stack Overflow用户

发布于 2017-03-07 17:16:02

当子组件不是父模板的一部分时,它们基本上是内容子组件。并且它们的作用域在父组件中。

例如,如果您有一个名为my-component的组件,并且在它的模板中有如下所示,

代码语言:javascript
复制
<parent [input]='somevar1' (output)='somemethod1()' >
   <child [input]='somevar2' (output)='somemethod2()' ></child>
</parent>

somevar1somevar2somemethod1somemethod2来自于my-component的范围。

基于这一理解,可以相当安全地说,parentchild可以被视为my-component范围内的兄弟姐妹。因此,您可以使用my-component范围在这两者之间进行通信。

例如,

代码语言:javascript
复制
@Component({
  selector: 'parent',
  template: `<h1>Parent</h1>
  {{awesomeInput}}
  <hr />
  <ng-content></ng-content>
  `
})
export class ParentComponent { 
   @Input() awesomeInput: string;
}

儿童部分,

代码语言:javascript
复制
@Component({
  selector: 'child',
  template: `<h1>Child</h1>
  <button (click)='sendAwesomeOutput()'>Click me!!</button>
  `
})
export class ChildComponent {
  @Output() awesomeOutput =  new EventEmitter();

  sendAwesomeOutput(){
    this.awesomeOutput.next('awesome output from child!!');
  }
}

在模板中使用上述组件的组件。

代码语言:javascript
复制
@Component({
  selector: 'my-app',
  template: `<h1>Hello {{name}}</h1>
  <hr />
  <parent [awesomeInput]="defaultInput" >
     <child (awesomeOutput)="getOutputFromChild($event)" ></child>
  </parent>
  `
})
export class AppComponent { 
  name = 'Angular';
  defaultInput = 'default value for parent';

  getOutputFromChild(val){
    this.defaultInput = val;
  }
}

更新

在父-子之间传递值的方式可能没有什么创造性,而且完全可以在模板本身中实现。更新柱塞

代码语言:javascript
复制
<parent awesomeInput="{{child1.awesomeOutput | async }}" >
     <child #child1 ></child>
</parent>

如果您必须处理任何事情,上面的内容会考虑场景。

看看这个柱塞!!

希望这能帮上忙!

票数 1
EN

Stack Overflow用户

发布于 2017-03-08 20:18:58

在没有使用ngModel、绑定或EventEmitter的情况下回答标题问题(因为它在模板之外不起作用),并且足够灵活,可以在每个子组件(角2.4 )中包含任何类型的内容,以下是其他实现的另一种方法:

示例:

在奥丁会议(“组织者”)上的“演讲者”。一次只能有一位演讲者讲话(出现)。第二次展示的人,向组织者传达他们的意图,组织者阻止其他演讲者发言,以便新的演讲者能够继续他们的演讲。

(演示屏幕截图减去其他嵌套内容:)

单击任意按钮将使所有演示者隐藏,但您刚才单击的按钮除外。

使用:

代码语言:javascript
复制
<organizer>
    <presenter>
        <h2>Thor</h2>
        <summary>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Incidunt ea nisi impedit aspernatur sint voluptatum odit aperiam, soluta, explicabo, nesciunt earum quo. Vel quod, ratione ullam deserunt commodi quaerat fugiat!</summary>
        <asgardian-power-point></asgardian-power-point>
    </presenter>
    <presenter>
        <h2>Loki</h2>
        <summary>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Incidunt ea nisi impedit aspernatur sint voluptatum odit aperiam, soluta, explicabo, nesciunt earum quo. Vel quod, ratione ullam deserunt commodi quaerat fugiat!</summary>
        <interjection></interjection>
        <lies></lies>
    </presenter>
    <presenter>
        <h2>Sif</h2>
        <summary>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Incidunt ea nisi impedit aspernatur sint voluptatum odit aperiam, soluta, explicabo, nesciunt earum quo. Vel quod, ratione ullam deserunt commodi quaerat fugiat!</summary>
        <asgardian-power-point></asgardian-power-point>
    </presenter>
</organizer>

organizer.component.html:

代码语言:javascript
复制
<ng-content></ng-content>

organizer.component.ts:

代码语言:javascript
复制
import {
    Component,
    ContentChildren,
    QueryList
} from '@angular/core';

import { PresenterComponent } from '../presenter/presenter.component';

@Component({
    selector: 'organizer',
    templateUrl: './organizer.component.html',
    styleUrls: ['./organizer.component.scss']
})

export class OrganizerComponent {

    @ContentChildren(PresenterComponent) presenters: QueryList<PresenterComponent>;

    stopPresenters() {
        this.presenters.forEach(function(item) {
            item.conclude();
        });
    }

}

presenter.component.html:

代码语言:javascript
复制
<div style="overflow:hidden;" [style.height]="expand ? 'auto' : '30px'">
    <button (click)="present()">Present</button>
    <ng-content></ng-content>
</div>

presenter.component.ts:

代码语言:javascript
复制
import {
    Component,
    Input,
    Inject,
    forwardRef
} from '@angular/core';

import { OrganizerComponent } from '../organizer/organizer.component';

@Component({
    selector: 'presenter',
    templateUrl: './presenter.component.html',
    styleUrls: ['./presenter.component.scss']
})

export class PresenterComponent {

    constructor(@Inject(forwardRef(() => OrganizerComponent)) private organizer:OrganizerComponent) {}

    @Input() expand: boolean = false;

    present() {
        this.organizer.stopPresenters();
        this.expand = true;
    }

    conclude() {
        this.expand = false;
    }

}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42653773

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档