javascript - Vanilla Custom Element repeater for <option>, <li>, <td> - Stack Overflow

I'm currently trying to implement a repeater WebComponent to allow the pany to easily create front

I'm currently trying to implement a repeater WebComponent to allow the pany to easily create front-end without depending on any framework (decision took by architecture).

Here's my current code:

<ul>
    <pany-repeat datas='[{"name": "NameValeur", "value": "valeurId"}, {"name": "NameObject", "value": "objectId"}]'>
        <li>${name}</option>
    </pany-repeat>
</ul>

<select name="" id="">
    <pany-repeat datas='[{"name": "NameValeur", "value": "valeurId"}, {"name": "NameObject", "value": "objectId"}]'>
        <option value="${value}">${name}</option>
    </pany-repeat>
</select>

The list is rightly working since it seems to have no limitation on which tag allowed inside, but the select is not allowing the customElement pany-repeat in it and by extension, break the feature and just display <option value="${value}">${name}</option>

Here's the source code of my WebComponent

class CompanyRepeater extends HTMLElement {
    connectedCallback() {
        this.render();
    }

    render() {
        let datas = JSON.parse(this.getAttribute('datas'));
        let elementType = this.getAttribute('element');
        this.template = this.innerHTML;
        console.log(elementType);

        let htmlContent = elementType !== null ? `<${elementType.toLowerCase()}>` : '';

        datas.forEach(elem => {
            htmlContent += this.interpolate(this.template, elem)}
        );

        htmlContent += elementType !== null ? `</${elementType.toLowerCase()}>` : '';

        this.innerHTML = htmlContent;
    }

    interpolate(template, obj) {
        for(var key in obj) {
            const pattern = "${" + key + "}";

            if(template.indexOf(pattern) > -1) {
                template = template.replace(pattern, obj[key]);
                delete(obj[key]);
            }
        };

        return template;
    }
}

customElements.define('pany-repeat', CompanyRepeater);

My question now is, how can I make it work, no matter what's the parent element? I've added a property element to my repeater, but it's not allowing me to declare more attribute, and it'll stick not work inside a table.

This is the only thing to prevent me from moving everything to WebComponent.

I'm currently trying to implement a repeater WebComponent to allow the pany to easily create front-end without depending on any framework (decision took by architecture).

Here's my current code:

<ul>
    <pany-repeat datas='[{"name": "NameValeur", "value": "valeurId"}, {"name": "NameObject", "value": "objectId"}]'>
        <li>${name}</option>
    </pany-repeat>
</ul>

<select name="" id="">
    <pany-repeat datas='[{"name": "NameValeur", "value": "valeurId"}, {"name": "NameObject", "value": "objectId"}]'>
        <option value="${value}">${name}</option>
    </pany-repeat>
</select>

The list is rightly working since it seems to have no limitation on which tag allowed inside, but the select is not allowing the customElement pany-repeat in it and by extension, break the feature and just display <option value="${value}">${name}</option>

Here's the source code of my WebComponent

class CompanyRepeater extends HTMLElement {
    connectedCallback() {
        this.render();
    }

    render() {
        let datas = JSON.parse(this.getAttribute('datas'));
        let elementType = this.getAttribute('element');
        this.template = this.innerHTML;
        console.log(elementType);

        let htmlContent = elementType !== null ? `<${elementType.toLowerCase()}>` : '';

        datas.forEach(elem => {
            htmlContent += this.interpolate(this.template, elem)}
        );

        htmlContent += elementType !== null ? `</${elementType.toLowerCase()}>` : '';

        this.innerHTML = htmlContent;
    }

    interpolate(template, obj) {
        for(var key in obj) {
            const pattern = "${" + key + "}";

            if(template.indexOf(pattern) > -1) {
                template = template.replace(pattern, obj[key]);
                delete(obj[key]);
            }
        };

        return template;
    }
}

customElements.define('pany-repeat', CompanyRepeater);

My question now is, how can I make it work, no matter what's the parent element? I've added a property element to my repeater, but it's not allowing me to declare more attribute, and it'll stick not work inside a table.

This is the only thing to prevent me from moving everything to WebComponent.

Share Improve this question edited Jul 28, 2018 at 22:27 Supersharp 31.3k11 gold badges102 silver badges147 bronze badges asked Mar 29, 2017 at 7:00 LoïcRLoïcR 5,0491 gold badge36 silver badges53 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 8

Solution 1

Put the repeater around your elements. Ex. for a minimal <data-repeater> custom element :

customElements.define('data-repeater', class extends HTMLElement 
{
  connectedCallback() 
  {
    const parent = this.firstElementChild
    const data = JSON.parse(this.dataset.values)

    const interpolate = obj => parent.innerHTML.replace(
      /\${(\w+)}/g,
      (match, key) => obj[key]
    )

    parent.innerHTML = data.map(interpolate).join('')
  }
})
<data-repeater data-values='[{"label": "Item 1", "id":1}, {"label": "Item 2", "id": 2}]'>
  <ul>
    <li id="${id}">${label}</li>
  </ul>
</data-repeater>

<data-repeater data-values='[{"name": "option 1", "value":1}, {"name": "option 2", "value": 2}]'>
  <select>
      <option value="${value}">${name}</option>
  </select>
</data-repeater>

Solution 2

Use customized built-in elements. You need to choose a new name for each standard element you want to extend, but you can reuse internally a unique base class to render the elements:

<select is="repeat-option" data-values="[...]">
   <option value="${value}">${name}</option>
</select>

customElements.define('select-repeater', class extends HTMLSelectElement {
  connectedCallback() { render(this) }
}, { extends: 'select' })

customElements.define('ul-repeater', class extends HTMLUListElement {
  connectedCallback() { render(this) }
}, { extends: 'ul' })

function render(view) {
  const data = JSON.parse(view.dataset.values)

  const interpolate = obj => view.innerHTML.replace(
    /\${(\w+)}/g,
    (match, key) => obj[key]
  )

  view.innerHTML = data.map(interpolate).join('')
}
<script src="https://rawgit./WebReflection/document-register-element/master/build/document-register-element.js"></script>


<ul is="ul-repeater" data-values='[{"label": "Item 1", "id":1}, {"label": "Item 2", "id": 2}]'>
    <li id="${id}">${label}</li>
</ul>


<select is="select-repeater" data-values='[{"name": "option 1", "value":1}, {"name": "option 2", "value": 2}]'>
		<option value="${value}">${name}</option>
</select>


If the rendering is very different depending on the element you could decide to create a class for rendering and to use derived classes for each type fo rendering ( select, ul, tr, td ), like in this example for tables.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745671055a4639404.html

相关推荐

  • 论文检测,文章检测,降AI率的工具

    1:文字滚筒鸭文字滚筒鸭作为市面上少见的全免费平台,文字滚筒鸭支持文章 AI 率检测、头条文章原创度分析、作文质量评估等多元场景,甚至能一键对比原文与改写后的相似度,所有功能统统 0 收费!精准算法秒出检测结果,不用充值会员,也无需分享裂变

    1小时前
    20
  • 精品网络时代:联通AS9929与10099的强强联合

    中国联通的网络架构犹如一座精心设计的立交桥系统,由AS4837、AS9929和AS10099三张骨干网共同构建。这三张网络各司其职又相互配合,形成了联通独具特色的网络服务体系。联通AS4837、AS9929和AS10099线路介绍一、线路组

    1小时前
    20
  • UnoCSS即时按需引用的原子css引擎

    什么是unocss?很多前端可能第一次听说这个词unocss是一个即时的原子CSS引擎,它可以让你用简短的类名来控制元素的样式,而不需要写复杂的CSS代码。当然,原子样式也有很多选择,最著名的就是 Tailwind。但由于Tailwind

    1小时前
    20
  • 如何增加 Elasticsearch 中的主分片数量

    要增加现有索引的主分片数量,直接修改是不可能的。因此,如果你想增加主分片的数量,必须重新创建索引。通常有两种方法:_reindex API 和 _split API。在这两种方法中,_split API 通常比 _reindex API 更

    1小时前
    20
  • 怎么用html写出哆啦A梦?

    用HTML和CSS来画哆啦A梦(Doraemon)是一项有趣且具有挑战性的任务。虽然HTML和CSS主要用于网页布局和样式,但通过巧妙的组合和定位,可以创建出相对简单的图形和图案。下面是一个简单的示例,展示了如何用HTML和CSS绘制哆啦A

    1小时前
    00
  • 谷歌云第三方SSH工具登录与一键重装系统

    一&#xff0c;设置 root 密码 先选择从浏览器打开 ssh 连接服务器切换到 root 账号&#xff0c;输入代码&#xff1a;sudo -i设置 root 密码&#xff0c;输入代码&

    1小时前
    00
  • 文章降 AI 痕迹方法与工具速览

    文章降AI的方法和工具汇总‌如下: 这几天又认真研究类了一下,想让 AI 生成的文章更自然,摆脱程式化痕迹,可尝试以下方法。借助 GPT、文字滚筒鸭,朱雀大模型检测器、豆包、kimi 等大模型,输入文本后,它们能通过调整结构、替换同义词等操

    1小时前
    00
  • MySQL 8.4 配置复制

    参考文档:.4enreplication-configuration.html1.先在源数据库主机的myf添加这几项代码语言:javascript代码运行次数:0运行复制[mysqld]server-id = 2binlog_forma

    1小时前
    00
  • MySQL8.4创建keyring给InnoDB表进行静态数据加密

    参考文档:.4enkeyring-plugin-installation.html.4enkeyring-hashicorp-plugin.html#keyring-hashicorp-vault-configuration1.首先

    1小时前
    10
  • 取消Win10开机系统选择倒计时,让电脑秒进系统

    取消Win10开机系统选择倒计时,让电脑秒进系统 近期,不少Win10用户反映在开机时会遇到一个选择系统的倒计时画面,这在一定程度上延缓了开机进程。对于追求高效启动体验的用户来说,这无疑是一个不必要的步骤。那么,如何取消这个倒计时,让电脑

    55分钟前
    00
  • 聊聊Spring AI Alibaba的ObsidianDocumentReader

    序本文主要研究一下Spring AI Alibaba的ObsidianDocumentReaderObsidianDocumentReadercommunitydocument-readersspring-ai-alibaba-star

    51分钟前
    00
  • 万字图解 Java 并发框架:ForkJoin、CountDownLatch、Semaphore、CyclicBarrier

    本文图多,内容硬核,建议收藏。在第一章节《1.6w 字图解 Java 并发:多线程挑战、线程状态和通信、死锁;AQS、ReentrantLock、Condition 使用和原理》,我们开启了 Java 高并发系列的学习,透彻理解 Java

    48分钟前
    00
  • HLS最全知识库

    HLS最全知识库副标题-FPGA高层次综合HLS(二)-Vitis HLS知识库高层次综合(High-level Synthesis)简称HLS,指的是将高层次语言描述的逻辑结构,自动转换成低抽象级语言描述的电路模型的过程。对于AMD Xi

    41分钟前
    00
  • 我用AI监控了奥特曼,当他一发推特AI就会自动给我打电话。

    上周我真的扛不住了。奥特曼这个孙贼,发了个X说,“要发一个礼拜的好东西”。我信了他的邪,明明出差1周,每天早上9点不到就要起来参加活动,但是晚上根本不敢睡觉,天天蹲到凌晨3点半,蹲到他们那边时间中午12点多,我才敢去睡觉。真的,那一整周,我

    39分钟前
    00
  • 面试官:从三万英尺角度谈一下Ceph架构设计(1)

    把面试官当陪练,在找工作中才会越战越勇大家好我是小义同学,这是大厂面试拆解——项目实战系列的第3篇文章,如果有误,请指正。本文主要解决的一个问题,Ceph为例子 如何描述项目的架构。一句话描述:主要矛盾发生变化10年前的技术和方案,放到10

    36分钟前
    00
  • 国产车载通信测试方案:车规级CAN SIC芯片测试技术解析

    随着智能网联汽车的快速发展,车辆内部电子控制单元(ECU)数量激增,动力总成、高级驾驶辅助系统(ADAS)、车身控制等功能对车载通信网络的稳定性与速率提出了更高要求。传统CAN FD总线在复杂拓扑中面临信号振铃、通信速率受限(实际速率通常低

    26分钟前
    00
  • 开源在线考试系统

    看到调问已经开始扩展在线考试的场景,试了一下,发现在线考试的基本能力都已经支持了。主要是考试中的各种计分功能,包括对每道题的选项设置分值计算、考试时间限制等,和官方了解了一下,考试中的其他各项能力也在逐步完善,有需求可以随时

    18分钟前
    00
  • Power BI 无公式实现帕累托图表

    帕累托分析(Pareto Analysis),也被称为8020法则、关键少数法则,是一种常用的管理工具,用于识别和处理影响业务的主要因素。看到李伟坚老师在Excel使用Vega实现了花式帕累托(参考:Excel 零公式实现高级帕累托图表)

    17分钟前
    00
  • 如何快速判断 Flutter 库是否需要适配鸿蒙?纯 Dart 库无需适配!

    在鸿蒙开发中,选择合适的 Flutter 库至关重要。纯 Dart 库因其跨平台特性,无需适配即可直接使用。但对于新手来说,如何判断一个库是否为纯 Dart 库呢?本文将为你提供清晰的判断方法和实用技巧。一、检查 pubspec.yaml

    14分钟前
    00
  • 推荐一个轻量级的监控平台并且支持移动端

    简介XUGOU 是基于Cloudflare构建的轻量化监控平台,专精于系统资源监控与可视化状态页面服务。该平台提供英文简体中文双语支持,满足全球化部署需求。面向开发者及中小团队,项目致力于提供高可用性的监控解决方案。核心功能与实现平台功能

    4分钟前
    00

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信