angular - 角度 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 专家,这是否是归档我正在尝试的内容的最佳方法。
提前致谢。
解决方案
你已经很接近了,我只是添加了一个指令来解决其余的问题。这是最后的堆栈闪电战
<ng-content select="...>
适用于静态内容投影。有时,您需要比这更强大的指令。
我从 Angular Material 代码库中获得了一个小技巧,并在几乎所有提供可定制模板的组件中使用它。
而不是写<ng-content select="button">
覆盖表的其他行并且只将button
s 放在最后一行,而是声明一个指令如下
@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
. 和你写的差不多,我只是把button
s 移到了 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
表明你可以输入任何东西。另外,我检索index
了id
这些对象并将其传递给一个函数。
openPerson(person, id) {
alert('Open ' + person + ' ' + id);
}
deletePerson(person, id) {
alert('Delete ' + person + ' ' + id);
}
推荐阅读
- python - Python缺少参数
- mysql - Oracle:获取具有相同日期的最后一条记录
- mongodb - MongoDB aggregation $graphLookup - find "connections" in common in collections of following relationships
- firebase - GDPR 和 Firebase 实时数据库 - 身份验证和用户识别:如何匿名化 Firebase 上的用户数据?
- javascript - 通过 JavaScript 添加的元素的样式不适用于我的 Phonegap 项目
- java - Java 整数常量 - 拆箱
- laravel-passport - 注册时的 Laravel Passport invalid_credentials
- c# - 如何通过 Code First 为实体框架上的列表属性创建唯一约束
- node.js - 节点和 Visual Studio
- javascript - 如何防止引导选项卡破坏非活动内容?[有状态标签切换]