将组件作为“参数”传递给Angular 2中的另一个组件
Posted
技术标签:
【中文标题】将组件作为“参数”传递给Angular 2中的另一个组件【英文标题】:Passing a component as an 'argument' to another component in Angular 2 【发布时间】:2016-04-07 03:58:03 【问题描述】:我是 Web 开发的新手,我刚刚开始构建 Angular 2 应用程序。此时我正在尝试创建一些 CRUD 组件/表单,但我发现我自己复制了很多代码。我不会问在使用 Angular2 设计 CRUD 应用程序时避免代码重复和实现组件可重用性的常见最佳实践是什么,因为帖子会被锁定。我宁愿专注于一个特定方面:
我有一个“CRUD 页面”,它有一个资源列表(实际上是一个 html 表)和几个打开“创建”、“读取”和“编辑”表单的按钮。该列表本身是一个单独的组件,并且创建/读取/编辑单独的组件也是如此。表格的每一行都包含另一个知道如何呈现资源项的组件。我将其称为<resource-item>
组件。但是,我有几个“CRUD 页面”,每个页面用于不同的资源。所以我想要的是为所有资源重用列表组件。所以要做的第一件事就是将 Inputs 或 Attributes 添加到列表组件中,以控制其标签。到目前为止,一切都很好。
但是<resource-item>
组件呢?我的应用程序的每个资源可能具有完全不同的结构。因此,对于不同的资源,我需要不同的组件,例如:<resource-a-item>
、<resource-b-item>
等。如何指定每次创建列表组件时要使用的资源项组件?
感谢您的宝贵时间。
【问题讨论】:
【参考方案1】:如果不同resource-x-item>
的列表是固定的,您可以使用 ngSwitch (ng-switch in Angular2)。
您还可以使用路由来动态添加组件。
如果上述方法不适用于您的用例,您可以使用 DynamicComponentLoader` (How to use angular2 DynamicComponentLoader in ES6?)
【讨论】:
【参考方案2】:这似乎非常适合内容嵌入。
Angular 2 带有一个名为 ng-content 的组件,它允许您插入外部 html/组件作为组件的内容。
您只需要在您希望内容显示在组件中的位置使用 。
例如:
import Component from 'angular2/core'
@Component(
selector: 'holder',
providers: [],
template: `
<div>
<h2> Here's the content I got </h2>
<ng-content></ng-content>
</div>
`,
directives: []
)
export class Holder
constructor()
您可以通过这种方式指定要从组件的父级注入的内容:
import Component from 'angular2/core';
import Holder from './holder';
@Component(
selector: 'my-app',
providers: [],
template: `
<div>
<h2>Hello name</h2>
<holder>
<div>yeey transcluded content name</div>
</holder>
</div>
`,
directives: [Holder]
)
export class App
constructor()
this.name = 'Angular2'
您可以查看工作示例here。
在您的情况下,您可以使列表行/项目成为可以接受某些内容以显示的组件。
【讨论】:
非常感谢。ng-content
拯救了我的一天。
这个答案非常有用。谢谢。我有个问题。有一种方法可以显示另一个组件,但只显示一些列,如姓名和姓氏。?提前致谢。我不会在 SOF 中提问,因为我不会
@toskv 我写了一条评论寻求你的帮助。提前致谢
做到这一点的方法是让你想要显示的组件是可配置的,让它有输入来显示/隐藏你需要的东西。如果您有更具体的案例,请告诉我,我很乐意提供帮助。【参考方案3】:
我正在研究可能对您有用的可重用组件场景。在本例中,configurator
组件具有基本结构,用于通过values
对象(来自form.values
)配置其他组件。
import Component, Input, EventEmitter, ViewEncapsulation from 'angular2/core';
@Component(
encapsulation: ViewEncapsulation.None,
selector: 'configurator',
template: `
<div [hidden]="!active">
<span (click)="active = false">×</span>
<h3> title </h3>
<form>
<ng-content></ng-content>
</form>
</div>
`
)
export class ConfiguratorComponent
@Input() title: string;
@Input() values: any = ;
@Input() emitter: EventEmitter<any>;
public active: boolean = false;
set(key: string, value?: any)
this.values[key] = value || !this.values[key];
if (this.emitter)
this.emitter.emit(this.values);
我在 host 组件中使用它作为它配置的组件的兄弟。
@Component(
directives: [
ConfiguratorComponent,
ResourceOneComponent,
],
pipes: [...],
providers: [...],
template: `
<configurator title="Resource One" #cfg [values]="one.values" [emitter]="configEmitter">
<label>Size:
<input type="number" min="0" #size [value]="cfg.values.size" (change)="cfg.set('size', size.value)">
</label>
</configurator>
<resource-one #one [emitter]="configEmitter"></resource-one>
`
)
class HostComponent
public configEmitter = EmitterService.get('resource_one');
资源组件可以是:
class ResourceOneComponent extends CRUDComponent
public values: size: 5 ;
private ngOnChanges()
if (this.emitter)
this.emitter.subscribe(values =>
// use values from configurator
);
这是我用来在同级组件之间进行通信的服务:
import Injectable, EventEmitter from 'angular2/core';
@Injectable()
export class EmitterService
private static _emitters: [ID: string]: EventEmitter<any> = ;
static get(channel: string): EventEmitter<any>
if (!this._emitters[channel])
this._emitters[channel] = new EventEmitter();
return this._emitters[channel];
编辑:对于您的用例来说,这可能是“矫枉过正”(:我刚刚看到其他答案,都适用于更简单的场景......我喜欢尽可能地将事情分开,所以每个组件都做一件事。我一直在研究可重用组件之间进行通信的方法,这个解决方案效果很好。认为分享(;
【讨论】:
以上是关于将组件作为“参数”传递给Angular 2中的另一个组件的主要内容,如果未能解决你的问题,请参考以下文章