将ControlValueAccessor包装在另一个组件中

时间:2019-04-06 18:13:24

标签: angular angular7 controlvalueaccessor ng-container

对于辅助项目,我实现了ControlValueAccessor的新实现(矩阵选择AKA:可在其中选择和取消选择单元格的表)。可以提供输入选项,以更改矩阵响应用户交互的行为。

我正在尝试创建一个“示例”页面,以列出具有各种选项集的矩阵选择控件(有点像https://material.angular.io/components/datepicker/overview)。对于每个示例,我想显示一个绑定值json,该绑定值在用户与控件和选项json交互时更新。

这很容易但是重复(我提供的变化比下面提供的还要多):

<h1>Matrix Selection Component</h1>
<h2>Basic</h2>
<app-matrix-selection [formControl]="peopleAttributesControl"></app-matrix-selection>
<h3>Json</h3>
<pre>{{data|json}}</pre>
<h3>Options</h3>
<pre>{{options||json}}</pre>

<h2>With Labels</h2>
<app-matrix-selection [formControl]="peopleAttributesControl" [keys]="people" [selectables]="subjects" firstCellValue="Students / Subjects"></app-matrix-selection>
<h3>Json</h3>
<pre>{{data|json}}</pre>
<h3>Options</h3>
<pre>{{options||json}}</pre>
...

请注意,对于每个示例,我必须输出json和options值。

在我的脑海中(可能是错误的),我想做的事情是这样的:

<h1>Matrix Selection Component</h1>
<h2>Basic</h2>
<app-example>
   <app-matrix-selection [formControl]="peopleAttributesControl"></app-matrix-selection>
</app-example>

<h2>With Labels</h2>
<app-example>
   <app-matrix-selection [formControl]="peopleAttributesControl" [keys]="people" [selectables]="subjects" firstCellValue="Students / Subjects"></app-matrix-selection>
</app-example>
...

并以这样一种方式定义AppExampleComponent,使其可以输出传入的任何组件的数据和选项(不仅是选择矩阵,还包括我可以使用所述属性定义的任何其他内容)。

我正在努力寻找任何资源来帮助我实现这一目标,我认为这可能是因为我正在努力说出我正在努力实现的目标。我希望一个组件包装另一个组件,以便它可以向我展示与该组件交互的效果。

我认为其他实现方法是选择1:

<h1>Matrix Selection Component</h1>
<h2>Basic</h2>
<app-matrix-selection [formControl]="peopleAttributesControl"></app-matrix-selection>
<app-example [data]="peopleAttributes"></app-example>

<h2>With Labels</h2>
<app-matrix-selection [formControl]="peopleAttributesControl" [keys]="people" [selectables]="subjects" firstCellValue="Students / Subjects"></app-matrix-selection>
<app-example [data]="peopleAttributes" [options]="withLabelsOptions"></app-example>
...

或选项2:

<h1>Matrix Selection Component</h1>
<app-matrix-selection-example title="Basic" [data]="peopleAttributes"></app-matrix-selection-example>

<app-matrix-selection-example title = "With Labels" [data]="peopleAttributes" [keys]="people" [selectables]="subjects" firstCellValue="Students / Subjects" [data]="peopleAttributes" [options]="withLabelOptions"></app-matrix-selection>
...

但是我真的不想为我以后创建的每个ControlValueAccessor创建一个示例组件。

我感觉这里缺少关键的Angular功能。如果没有,您将如何处理?

1 个答案:

答案 0 :(得分:0)

解决方案一-使用ng-content

我忘记了一个非常基本的概念-满足孩子们的需求!以下链接提供了帮助:https://medium.com/@tkssharma/understanding-viewchildren-viewchild-contentchildren-and-contentchild-b16c9e0358e

暂时忘记数据和选项要求,将导致:

<app-example title="Basic">
    <app-matrix-selection [formControl]="peopleAttributesControl"></app-matrix-selection>
</app-example>

示例组件如下所示:

<h2>{{title}}</h2>
<ng-content></ng-content>

ng-content将使用元素标签定义的元素输出到屏幕。

解决方案二-动态组件加载程序

第二部分要求需要动态加载组件:https://angular.io/guide/dynamic-component-loader

将示例转移到服务后,我得到了以下模板:

<h1>Matrix Selection Component</h1>
<app-example *ngFor="let example of examples" [title]="example.title" [example]="example"></app-example>

干净得多!

示例对象的属性之一是Angular核心组件类型,可以使用app-example组件中的ComponentFactoryResolver动态加载它。请按照上面Angular.io链接中的说明进行操作。

示例组件的模板随后可以处理重复结构:

<h2>{{title}}</h2>
<ng-template appExample></ng-template>
<h3>Bound Data Json</h3>
<pre>{{ example.componentAttributes.data | json }}</pre>
<div *ngIf="example.componentAttributes.options">
    <h3>Options Json</h3>
    <pre>{{ example.componentAttributes.options | json }}</pre>
</div>

需要注意的是,我将来所有的组件都必须具有数据和选项属性,这些属性可以通过实现接口来强制执行-但这对我来说很好。