Angular 2:当您不知道 childComponent 的类时,如何将 childComponent 属性发送给 parent?
Posted
技术标签:
【中文标题】Angular 2:当您不知道 childComponent 的类时,如何将 childComponent 属性发送给 parent?【英文标题】:Angular 2 : How do I send childComponent properties to parent when you don't know the childComponent's class? 【发布时间】:2016-10-18 13:28:58 【问题描述】:好的,这就是我想要实现的目标:
我有这个组件:
import Component, Output, EventEmitter, OnInit from '@angular/core';
@Component(
selector: 'like',
template: '<p>this is the like component<p>'
)
export class LikeComponent implements OnInit
title: string = 'Like Component';
@Output() sendTitle = new EventEmitter();
ngOnInit()
this.sendTitle.emit(title: this.title);
我想将标题从它发送给父母:
import Component, Input from '@angular/core';
@Component(
moduleId: module.id,
selector: 'panel',
template: `
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">title</h2>
</div>
<div class="panel-body">
<ng-content (sendTitle) = "receiveTitle($event)"></ng-content>
</div>
</div>
`
)
export class PanelComponent
title = 'default title';
receiveTitle(arg)
this.title = arg.title;
console.log(arg);
然后我可以将PanelComponent
与我想包装在面板中的每个组件一起重用:
<panel>
<like></like>
</panel>
<panel>
<another-component></another-component>
</panel>
<panel>
<exemple-component></exemple-component>
</panel>
每次显示Panel
组件时,它都会尝试从事件中获取标题(如果存在)。
这似乎不适用于 ng-content,因为它与常规父/子组件一样?我对 angular 2 不熟悉,因此非常感谢您的反馈!
tl;dr :我想让父母知道孩子的属性,但孩子不能具体(这就是我使用<ng-content>
的原因)。
简而言之,我不想像这样通过input
这样做:
<panel [title] = "'This is the panel title of the like component'">
<like></like>
</panel>
<panel [title] = "'This is the panel title of the another-component'">
<another-component></another-component>
</panel>
【问题讨论】:
【参考方案1】:经过大量搜索,我找到了类似 Sasxa 的解决方案,但可以与任何子组件一起使用。关键是@ComponentChild
的“选择器”可以是字符串。
interface TitledComponent
title?: string;
@Component(
selector: 'panel',
template: `<div class="panel">
<h2>title</h2>
<ng-content></ng-content>
</div>`
)
export class PanelComponent
title = 'default title';
@ContentChild('titled') childComponent: TitledComponent;
ngAfterContentInit()
if (this.childComponent)
this.title = this.childComponent.title || 'default title';
而且 html 必须是
<panel>
<like #titled></like>
</panel>
<panel>
<other #titled></other>
</panel>
<panel>
<p>I don't have a title</p>
</panel>
<panel>
<like></like>
<!-- This won't be picked up -->
</panel>
【讨论】:
哇,谢谢@jladan,这正是我想要的!好主意!【参考方案2】:试试这个:
export class PanelComponent
title = 'default title';
@ContentChild(LikeComponent) like: LikeComponent;
ngAfterContentInit()
this.title = this.like.title;
【讨论】:
我真的很想使用你的代码,但是因为我想重用PanelComponent
来包装我想要的所有其他组件,所以这行不通。【参考方案3】:
如果要使用事件方式,可以使用element.dispatchEvent
创建冒泡事件。 EventEmitter
事件不会冒泡,只能与 (xxx)
绑定一起使用。
在子组件中看起来像
constructor(private elRef:ElementRef, private renderer:Renderer)
onBlur($event)
this.renderer.invokeElementMethod(this.elRef.nativeElement,
'dispatchEvent',
[new CustomEvent('input-blur', bubbles: true )]);
另见我的类似回答in Angular2 how to know when ANY form input field lost focus
【讨论】:
好吧,我真的不想使用事件,这对我来说似乎是一种可能的方法。我只想从不知道孩子是否可以说title
财产的父母那里获得孩子财产。我想尝试一下,如果它返回一个字符串【参考方案4】:
我认为应该在面板模板中这样做
<h2>title</h2>
<panel class="col-xs-6 col-md-4">
<like (sendTitle)="receiveTitle($event. title)"></like>
</panel>
并在组件中设置:
receiveTitle(title)
this.title = title;
console.log(event);
您像发送(单击)事件一样发送输出事件。 () 表示你从 html 向组件提交一些东西,[] 表示你从组件绑定一些东西到 html。
希望这就是你的意思!
不清楚为什么要使用 ng-content ? 每次点击,父标题都会从子组件更新。
【讨论】:
我正在使用<ng-content>
,因为我希望这个组件可以与我想要的任何其他组件一起使用。简而言之,它只是将一个组件包装在一个漂亮的面板中,但我想从孩子那里得到panel-title
。从LikeComponent
,我虽然可以使用OnInit() this.sendTitle.emit(title: this.title);
,所以它会在启动时发送标题?或者我应该通过constructor
发送它。
我目前看不到没有面板用户支持的方法。如果用户添加了模板变量或属性(以指令为目标),则可以使用@ContentChildren()
对其进行查询。我认为 Angular 团队最终会改进这一点。您不是第一个要求使用此功能的人。以上是关于Angular 2:当您不知道 childComponent 的类时,如何将 childComponent 属性发送给 parent?的主要内容,如果未能解决你的问题,请参考以下文章
当您不知道内容的大小时,如何在 react native 中为高度设置动画?
当您不知道 Swift 中的项目类型时,如何解码嵌套的 JSON 数据? [复制]
当您不知道页数时,如何使用 Node.js 在 while 循环中向 API 发出多个分页 GET 请求?