无法从导入的对象中运行JavaScript标记的模板

问题描述

我正在尝试将网站JavaScript转换为与webpack捆绑兼容的卡盘,基本上我需要导出/导入多页网站所需的脚本,然后将它们打包为每页1个文件,但这确实给我带来了一些麻烦

该脚本以前可以很好地运行,但是现在它不能像以前那样运行

我有一个使用字符串Listerals和字符串操作的模板程序功能,该模板程序功能最初是受this帖子的启发,但是却有所修改

   export const templater = (parts) => {
        return (data) => {
            let res = parts[0];
    
            for (let i=1; i < parts.length; i++) {
                const val = arguments[i];
                if (typeof val == "function") {
                    res += val(data);
                } else {
                    if (data) {
                        if(data.hasOwnProperty(val)) {
                            res += data[val];
                        }
                    }
                }
    
                res += parts[i];
            }
            return res;
        }
    };

我有一个脚本来处理字符串文字,它是一个带有键“ template”的对象,该对象调用导入的templater函数

import {templater} from '../functions/cc-templater-function.js';

export let complianceHandler = {
    template: templater`
        <div class="compliance-overlay">
            <div id="compliance-wrapper" class="compliance-wrapper ${'type'}">
                <p class="compliance-message">${'message'}</p>
                <button id="compliance-yes" data-answer="yes">Yes</button><button id="compliance-no" data-answer="no">No</button>
            </div>
        </div>
    `
}

我有这个脚本,它将JavaScript对象传递给在templater函数中使用它的处理程序

import {complianceHandler } from './objects/cc-compliance-handler-object.js';
        
export let testObject = {
   remove: () => {
      document.querySelector('#myelem').insertAdjacentHTML("beforeend",complianceHandler.template({
                        message: 'Are you sure you want to do this?'
      }));
   }
}

上面是真实代码的简化/剥离版本

调用testObject.remove()时出现此错误Cannot read property 'call' of undefined 我在任何地方都看不到名为call方法/函数在这一点上我有点迷失于如何调试和修复此问题

  1. 与webpack捆绑在一起时,一切都很好
  2. 在未与webpack捆绑在一起且未导出/导入的普通代码中,所有内容都以这种方式工作(旧代码

有人知道如何解决这个问题吗?我试图以各种方式修改代码,但是我仍然遇到相同的错误

解决方法

export let complianceHandler = {
    template: templater`
        <div class="compliance-overlay">
            <div id="compliance-wrapper" class="compliance-wrapper ${'type'}">
                <p class="compliance-message">${'message'}</p>
                <button id="compliance-yes" data-answer="yes">Yes</button><button id="compliance-no" data-answer="no">No</button>
            </div>
        </div>
    `
}

这将导出具有通过调用template函数生成的templater string 属性的对象。

稍后,您要导入此文件并尝试调用 template属性。由于是字符串,因此调用毫无意义:

complianceHandler.template({
  message: 'Are you sure you want to do this?'
})

听起来您想做的就是改为将template设为 function

export let complianceHandler = {
    template: ({ type,message }) => templater`
        <div class="compliance-overlay">
            <div id="compliance-wrapper" class="compliance-wrapper ${type}">
                <p class="compliance-message">${message}</p>
                <button id="compliance-yes" data-answer="yes">Yes</button><button id="compliance-no" data-answer="no">No</button>
            </div>
        </div>
    `
}

注意,我还修复了模板占位符(${type},而不是${'type'},因此使用了变量,而不是文字字符串'type')。还应注意,如果要生成有效的HTML ,则在插入变量之前,应先对变量进行HTML编码,除非您希望变量为HTML而不是文本。