gpt4 book ai didi

javascript - 使用自定义元素内容作为项目模板

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:21:34 25 4
gpt4 key购买 nike

我正在为我们的内部框架编写可重用的组件,以抽象出一些猴子代码。大多数场景都是用插槽实现的,效果很好。但是,某些场景需要在 for 循环内渲染模板,不幸的是,那里不支持插槽。

我想出了以下(有效)代码:

<template>
<div class="form-group">
<label for.bind="titleSafe" class="control-label">{title}</label>
<select id.bind="titleSafe" value.bind="value" class="form-control">
<option repeat.for="item of itemsSource" >
<template replaceable part="item-template" containerless>${item}</template>
</option>
</select>
</div>
</template>

IMO,这段代码有多个问题,使其不适合将其包含在框架中:

  • 它不像插槽那样支持默认模板,因此当您只有 1 个可替换部分时,语法不必要地冗长
  • 必须在我的项目中使用 2 种不同的模板系统(插槽 + 替换部分)似乎非常违反直觉,并且肯定会在我的开发团队中造成困惑/错误
  • 当您在我上面提供的示例中使用模板部分时,您需要知道我在我的 for 循环中将“item”声明为迭代器,以便正确构建您的模板

因此我开始寻找替代方案。经过一些研究,我想出了这样的事情:

<template>
<div class="form-group">
<label for.bind="titleSafe" class="control-label">{title}</label>
<select id.bind="titleSafe" value.bind="value" class="form-control">
<option repeat.for="item of itemsSource" >
<!-- I want to insert my custom element here -->
</option>
</select>
</div>
<slot></slot>
</template>

以上是我的select-item 自定义元素。然后我还会为可重复项目的模板创建另一个自定义元素,比如 select-item-template,然后我会像这样一起使用这两个元素:

<select-item title="myTitle" items-source="myItems">
<select-item-template><span>${myItemsProperty}</span></select-item-template>
</select-item>

这种方法的优势在于您可以使用一个默认槽创建复杂的“根”自定义元素。在这个插槽中,您可以定义多个自定义“子”元素,根元素在初始化时可以搜索这些元素(我知道您可以使用 @child 和 @children 装饰器来执行此操作,因此涵盖了该部分)。不过,我对如何在我的根自定义元素中使用这些自定义子元素的内容有点迷茫。我将如何使用上面示例中的 span 元素并准备它的内容在中继器中呈现?是否可以将重复的 item 设置为模板的数据源,这样我就不必在模板中指定 item 了?我希望我没有说得太冗长,但我想解释一下我的功能要求是什么。如果您有任何资源可以为我指明正确的方向,我将不胜感激!

最佳答案

使用processContent 属性将元素内容转换为部分替换。该组件仍将在内部使用 replace-part,但该组件的使用者不会看到此实现细节。

https://gist.run?id=2686e551dc3b93c494fa9cc8a2aace09

picker.html

<template>
<label repeat.for="item of itemsSource" style="display: block">
<input type="radio" value.bind="item" checked.bind="value">
<template replaceable part="item-template">${item}</template>
</label>
</template>

picker.js

import {bindable, processContent} from 'aurelia-templating';
import {bindingMode} from 'aurelia-binding';
import {FEATURE} from 'aurelia-pal';

@processContent(makePartReplacementFromContent)
export class Picker {
@bindable itemsSource = null;
@bindable({ defaultBindingMode: bindingMode.twoWay }) value = null;
}


function makePartReplacementFromContent(viewCompiler, viewResources, element, behaviorInstruction) {
const content = element.firstElementChild;
if (content) {
// create the <template>
const template = document.createElement('template');

// support browsers that do not have a real <template> element implementation (IE)
FEATURE.ensureHTMLTemplateElement(template);

// indicate the part this <template> replaces.
template.setAttribute('replace-part', 'item-template');

// replace the element's content with the <template>
element.insertBefore(template, content);
element.removeChild(content);
template.content.appendChild(content);

return true;
}
}

用法

<template>
<require from="picker"></require>

<h1>Default Item Template</h1>

<picker items-source.bind="colors" value.bind="color"></picker>

<h1>Custom Item Template</h1>

<picker items-source.bind="colors" value.bind="color">
<em css="color: ${item}">
${item}
</em>
</picker>
</template>

关于javascript - 使用自定义元素内容作为项目模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43306744/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com