是否可以在运行时动态定义自定义组件模板内元素的类型?
我想避免重复 button
的内部内容和a
以下示例中的元素:
<template>
<button if.bind="!isLinkBtn">
<span class="btn-icon">${icon}</span>
<span class="btn-text">${contentText}</span>
</button>
<a if.bind="isLinkBtn">
<!--
The content is a 1:1 duplicate of the button above which should be prevented
somehow in order to keep the view DRY
-->
<span class="btn-icon">${icon}</span>
<span class="btn-text">${contentText}</span>
</a>
</template>
是否可以这样写:
<template>
<!--
The type of element should be defined at runtime and can be a standard HTML "button"
or an anchor "a"
-->
<element type.bind="${isLinkBtn ? 'a' : 'button'}">
<span class="btn-icon">${icon}</span>
<span class="btn-text">${contentText}</span>
</element>
</template>
我知道 <compose view="${widget.type}-view.html"></compose>
的动态合成但据我所知,这不允许我创建默认的 HTML 元素,而只能创建自定义组件,对吗?
我在 Aurelia Gitter 上提出了这个问题,Erik Lieben 建议使用 @processContent(function)
装饰器,替换给定 function
内的内容并返回true
让 Aurelia 处理它。
不幸的是,我不知道如何实际应用这些说明,我希望在这里有一些替代方法或一些有关如何实际实现这一点的细节。
<小时/>编辑
我已经创建了相应的 feature request 。尽管已经提供了可能的解决方案,但我希望看到一些更简单的方法来解决这个问题;)
最佳答案
当您想要重用 HTML 片段时,请使用 compose。这样做不会创建新的自定义元素。它仅包含每个 compose 元素所在位置的 HTML。因此,所包含的 HTML 的 View 模型与其组成元素的 View 模型相同。
看看这个 GistRun:https://gist.run/?id=36cf2435d39910ff709de05e5e1bedaf
自定义链接.html
<template>
<button if.bind="!isLinkBtn">
<compose view="./custom-link-icon-and-text.html"></compose>
</button>
<a if.bind="isLinkBtn" href="#">
<compose view="./custom-link-icon-and-text.html"></compose>
</a>
</template>
自定义链接.js
import {bindable} from 'aurelia-framework';
export class CustomLink {
@bindable() contentText;
@bindable() icon;
@bindable() isLinkBtn;
}
自定义链接图标和文本.html
<template>
<span class="btn-icon">${icon}</span>
<span class="btn-text">${contentText}</span>
</template>
consumer.html
<template>
<require from="./custom-link"></require>
<custom-link content-text="Here is a button"></custom-link>
<custom-link is-link-btn.bind="true" content-text="Here is a link"></custom-link>
</template>
您可能希望将它们拆分为单独的元素,例如 <custom-button>
和<custom-link>
而不是使用 is-link-btn
控制他们的演示属性。您可以使用相同的技术来重用公共(public) HTML 部分,并通过装饰器组合来重用公共(public)代码。
查看此要点运行:https://gist.run/?id=e9572ad27cb61f16c529fb9425107a10
回复您的“不太详细”的评论
您可以将其压缩为一个文件并避免 compose
使用上述技术GistRun和 inlineView
装饰器:
查看此要点运行:https://gist.run/?id=4e325771c63d752ef1712c6d949313ce
您所需要的只是这个文件:
自定义链接.js
import {bindable, inlineView} from 'aurelia-framework';
function customLinkElement() {
return function(target) {
bindable('contentText')(target);
bindable('icon')(target);
}
}
const tagTypes = {button: 'button', link: 'a'};
@inlineView(viewHtml(tagTypes.button))
@customLinkElement()
export class CustomButton {
}
@inlineView(viewHtml(tagTypes.link))
@customLinkElement()
export class CustomLink {
}
function viewHtml(tagType) {
let result = `
<template>
<${tagType}${tagType === tagTypes.link ? ' href="#"' : ''}>
<span class="btn-icon">\${icon}</span>
<span class="btn-text">\${contentText}</span>
</${tagType}>
</template>
`;
return result;
}
关于aurelia - 在运行时更改元素类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42557158/