我有一个工厂函数,如果这不是标准行话,我指的是一个返回对象的函数。这个工厂函数称为
Person
。我现在要说的是 - 我不想听到“使用构造函数”。工厂功能更好。
我还有一个对象数组,
allPeople
是使用这个工厂函数制作的。
如果从我对“工厂函数”的使用中不清楚,这些对象实际上是包含 getter 方法的对象,在本例中是
getPerson
,以及其他函数(生成的对象通过闭包作用域来区分)。要获取实际数据,必须对 getPerson()
对象(由 Person
函数生成的对象)调用 Person
。
我想我应该解释一下,这样我们就处于同一基础上。
我正在尝试使用 Handlebars 为
Person
中的每个 allPeople
对象插入一个元素。对于每个 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)时,会发生以下错误:
.....
^ 期待“ID”,结果“无效”<p>{{this.getPerson().theName}
如何正确实现这个设计?
我从您的帖子中了解到您并不是在寻找反对使用此“工厂功能”的建议。然而,我觉得如果我没有声明我没有看到这段代码的价值,我的帖子就不完整,而且我认为这会让事情变得不必要的复杂。
但是继续“工厂功能”。
有问题。事实上,您没有在每个赋值
var
和 const
之前放置 let
或 theName = givenName
或 age = givenAge
意味着 theName
和 age
是全局范围的,因此对 getPerson()
的任何调用将返回提供给最后一次调用 theName
的参数的 age
和 Person()
。
一旦解决了这个问题,我建议让您的模板幸福地不知道“工厂功能”。您可以通过将
allPeople
数组映射到每个人都能理解的普通对象来做到这一点:
const allPeople = [
Person('Jim', 32),
Person('Lily', 46)
].map(person => person.getPerson());
您的(简化的)模板将变为:
{{#each people}}
<p>{{theName}}</p>
<p>{{age}}</p>
{{/each}}
这里是一个工作示例的小提琴。
如果出于某种原因,您确实希望模板处理
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}}
并且这里是一个关于这个例子的小提琴。