首页 > 解决方案 > 角度 6+。如何扩展模板添加新的动作,如 JSF?

问题描述

我正在尝试在 Angular6 + 中实现 JSF 的页面组合概念,但我不知道如何启动它。这是我需要的:

1) 模板页面,例如搜索页面,其中有字段、搜索操作和搜索结果表的占位符。

2) 扩展模板并添加其字段、操作和结果的页面

3) 可以扩展#2 并向结果数据表行添加自定义操作。

下图描述了上面的每个项目:

1) 搜索页面通用模板

搜索页面模板

2) 自定义搜索页面(扩展#1)

无需操作的自定义搜索页面

3)添加到搜索页面的自定义操作(扩展#2)

自定义搜索

3.1) 与#3 类似的页面,但对结果行有不同的操作(扩展#2)

备用自定义页面

我想要的是基于几个基本模板(#1)标准化所有页面,并重用特定页面添加新操作(#2)。结果,#3 将显示为最终用户,它可能会在不同的地方使用,只需稍作更改,例如,我可以搜索员工并打开它,或者我可以使用相同的搜索页面查找员工,而不是打开它的记录,我将选择它来填写其他表格的字段。在这个例子中,我需要做的只是扩展#2 并添加将打开或只是查找员工并设置为其他表单的特定操作。

PS:开发者可以在占位符中添加组件。

更新:

22/11/2018

根据 Bunyamin Coskuner 的建议,我很快实现了一个示例,但现在我被困在一个特定的行为上。

我创建了一个 StackBlitz 项目并发布了我的示例代码:

https://stackblitz.com/edit/angular-s2wkpw

只需单击“搜索”并查看结果。操作按钮仅添加在最后一行。在每一行中复制这些按钮的最佳方法是什么?

PS:每个按钮必须根据行中的内容将正确的参数传递给控制器​​。

我想问一下 Angular 专家,这是否是归档我正在尝试的内容的最佳方法。


提前致谢。

标签: angular

解决方案


你已经很接近了,我只是添加了一个指令来解决其余的问题。这是最后的堆栈闪电战

<ng-content select="...>适用于静态内容投影。有时,您需要比这更强大的指令。

我从 Angular Material 代码库中获得了一个小技巧,并在几乎所有提供可定制模板的组件中使用它。

而不是写<ng-content select="button">覆盖表的其他行并且只将buttons 放在最后一行,而是声明一个指令如下

@Directive({ selector: '[appPersonSearchButtons]' })
export class TemplatePersonSearchButtonsDirective {
    constructor(public template: TemplateRef<any>) { }
}

该指令可能看起来没有多大作用,我向你保证确实如此!它具有单一属性,即template. 它被注入这里是因为我们将只使用这个指令ng-template!如果你在任何其他元素上使用这个指令,ng-template你会得到一个错误!

您应该将此指令放入declarations模块的数组中

declarations: [ ... TemplatePersonSearchButtonsDirective ... ]

现在,是时候改变<ng-content select="button">一些东西了。首先,让我们确定这个组件的消费者是否在他们的模板中使用了这个指令。

我将此行添加到TemplatePersonSearchComponent

@ContentChild(TemplatePersonSearchButtonsDirective) buttons: TemplatePersonSearchButtonsDirective;

我已更改<tr *ngFor...>为关注

<tr *ngFor="let person of persons; let i = index">
  <td width="80%">{{person}}</td>
  <td>
    <ng-container *ngIf="buttons">
      <ng-container *ngTemplateOutlet="buttons.template;
        context: { $implicit: person, index: i}">
      </ng-container>
    </ng-container>
  </td>
</tr>

ngTemplateOutlet是一个将 aTemplateRef作为输入的指令(buttons.template在本例中来自)。此外,您也可以传递上下文,以便向用户公开一些数据(稍后会派上用场)。

让我们在我们的employee-search-component. 和你写的差不多,我只是把buttons 移到了 an 里面,ng-template如下

<app-template-person-search>
  <ng-template appPersonSearchButtons let-personObj let-id="index">
    <button (click)="openPerson(personObj, id)">Open</button>
    <button (click)="deletePerson(personObj, id)">Delete</button>
  </ng-template>
</app-template-person-search>

请记住,我们将上下文定义为context: { $implicit: person, index: i}"

因为,我们定义person$implicit,您可以编写任何以 开头的内容let-来检索该对象。我选择personObj表明你可以输入任何东西。另外,我检索indexid这些对象并将其传递给一个函数。

openPerson(person, id) {
    alert('Open ' + person + ' ' + id);
}

deletePerson(person, id) {
    alert('Delete ' + person + ' ' + id);
}

推荐阅读