aurelia - 在运行时更改元素类型

标签 aurelia aurelia-templating

是否可以在运行时动态定义自定义组件模板内元素的类型?

我想避免重复 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使用上述技术GistRuninlineView装饰器:

查看此要点运行: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/

相关文章:

javascript - 我如何在 Aurelia 中使用 Promises?

javascript - paper-drawer-toggle 在点击后不关闭菜单

javascript - 在 Aurelia 中,我可以从我的包含 View 模型中绑定(bind)一个函数以供我的自定义元素调用吗?

typescript - 引用我的 TypeScript 模块时出错 TS2307 : Cannot find module

javascript - 如何在 View 外评估 Aurelia 插值表达式?

forms - AureliaJS - 从父调用子函数

javascript - Aurelia - 默认情况下自定义元素不继承绑定(bind)上下文。可以吗?

Aurelia 快速启动不起作用

typescript - Aurelia:自定义属性的主要属性的数据绑定(bind)问题