javascript 如何在Handlebars模板中调用工厂函数的getter方法?

6l7fqoea  于 2023-09-29  发布在  Java
关注(0)|答案(1)|浏览(112)

我有一个工厂函数,如果这不是标准的行话,我指的是一个返回对象的函数。这个工厂函数叫做Person。我现在要说-我不想听到'使用构造函数'。工厂功能更好。
我也有一个对象数组,allPeople使用这个工厂函数。
如果我使用“工厂函数”时不清楚,这些对象实际上是包含getter方法的对象,在本例中是getPerson,以及其他函数(产生的对象由闭包作用域区分)。要获取实际数据,必须在Person对象(由Person函数生成的对象)上调用getPerson()
我想我应该解释一下,这样我们就有了相同的基础。
我尝试使用Handlebars为allPeople中的每个Person对象插入一个元素。对于每个Person<p>元素将显示name值,另一个<p>元素将显示age值。
下面我包括js文件和html文件。

script.js

//Factory Function
const Person = (givenName, givenAge) => {
    theName = givenName;
    age = givenAge;
    const getPerson = () => {
        const obj = { theName, age };
        return { theName, age };
    }
    return {getPerson};
}
//DOM Element Access
const templateElement = document.getElementById('templateHB');
const templateDestination = document.getElementById('destination');
//Context
allPeople = [
    Person('Jim', 32),
    Person('Lily', 46)
];
const context = {
    people: allPeople
};
//Templating
const template = Handlebars.compile(templateElement.innerHTML);
const compiledHTML = template(context);
templateDestination.innerHTML = compiledHTML;

index.html

<!DOCTYPE html>
<html lan="en">
<head>
    <meta charset"UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>For SO use</title>
    <script src="./script.js" defer></script>
    <script src="./handlebars.js"></script>
    <script id="templateHB" type="text/x-handlebars-template" defer>
        {{#each people}}
        <p>{{this.getPerson().theName}}</p>
        <p>{{this.getPerson().age}}</p>
        {{/each}}
    </script>
</head>
<body>
    <div id="destination">

    </div>
</body>
</html>

当我在浏览器中打开index.html时(我尝试过Google Chrome和Firefox),会发生以下错误:
..... <p>{{this.getPerson().theName} ^应为'ID',但得到'INVALID'
如何正确实现此设计?

pftdvrlh

pftdvrlh1#

我从你的帖子中了解到,你并不是在寻找反对使用这个“工厂功能”的建议。然而,我觉得我的帖子是不完整的,如果我没有说明我没有看到这段代码中的价值,我认为它使事情变得不必要的复杂。
但是让我们继续使用“工厂功能”。
有一个问题。事实上,您没有将varconstlet放在每个赋值theName = givenNameage = givenAge之前,这意味着theNameage是全局范围的,因此任何对getPerson()的调用都将返回上次调用Person()时提供的参数theNameage
一旦这个问题解决了,我建议你让你的模板幸福地不知道“工厂函数”。您可以通过将allPeople数组Map到每个人都能理解的普通对象来做到这一点:

const allPeople = [
  Person('Jim', 32),
  Person('Lily', 46)
].map(person => person.getPerson());

您的(简化)模板将变为:

{{#each people}}
  <p>{{theName}}</p>
  <p>{{age}}</p>
{{/each}}

Here是一个工作示例的小提琴。
如果出于某种原因,你真的希望你的模板处理getPerson方法,那么我认为你需要一个自定义的Handlebars助手:

Handlebars.registerHelper('getPersonProperty', function (person, property) {
  return person.getPerson()[property];
});

在您的模板中使用此辅助对象将如下所示:

{{#each people}}
  <p>{{getPersonProperty this 'theName'}}</p>
  <p>{{getPersonProperty this 'age'}}</p>
{{/each}}

here就是一个例子。

相关问题