所以,我对JavaScript和Meteor都很陌生,所以我只知道一些事情。
同时学习JavaScript和Meteor我为自己设定了一个挑战,即在单击单元格的情况下制作一个包含单个计数器的3乘3字段,如果单击单元格,则会计算。
我达到了我的第一个目标:http://9fields.meteor.com/
我为自己设定的第二个目标是尽量使其易于扩展。说,我想制作相同的字段但是7x7。
每个单元格都有自己的模板。
<template name="zelle1">
<td class="box">
<p class="textinbox">{{counter}}</p>
</td>
</template>
每个单元格都有自己的计数器,每个单元格都有一个事件处理程序和一个帮助程序来注册单击
Template.zelle1.helpers({
counter: function () {
return Session.get("counter1");
}
});
Template.zelle1.events({
"click td": function() {
return Session.set("counter1", Session.get("counter1")+1);
}
});
然后我再将代码粘贴8次并替换了数字。
我认为唯一能达到第二个目标标准的是我创建表格的方式。
<table>
{{#each zellen}}
{{#if this.newrow}}
<tr></tr>
{{> UI.dynamic template=this.name}}
{{else}}
{{> UI.dynamic template=this.name}}
{{/if}}
{{/each}}
</table>
结合这个数组(数组是正确的词?)
Template.body.zellen = [
{name: "zelle1", newrow: false},
{name: "zelle2", newrow: false},
{name: "zelle3", newrow: false},
{name: "zelle4", newrow: true},
{name: "zelle5", newrow: false},
{name: "zelle6", newrow: false},
{name: "zelle7", newrow: true},
{name: "zelle8", newrow: false},
{name: "zelle9", newrow: false},
];
我的问题:我是否必须为这9个字段制作9个模板和9个助手以及9个事件?这意味着如果我想制作7x7字段,我需要粘贴代码49次?或者有更有效的方法吗?
已经感谢您阅读本文!
答案 0 :(得分:1)
让我们提出解决问题的第三种方法:) 您始终可以使用以下内容来填充多个Session变量:
var fieldSize = 9;
for (i = 1; i <= fieldSize; i++) {
Session.set("counter" + i, i); // sets 9 Session variables
}
或者在Session
内使用数组。它甚至可以是一个对象数组:
var fieldSize = 9;
var fields = [];
for (i = 1; i <= fieldSize; i++) {
fields.push({name: i, count: i});
}
Session.set("fields", fields);
这与使用ReactiveVar
的方法基本相同,只是使用全局变量(Session
)而不是范围变量。您可以在整个应用程序中访问Session
内存储的内容。
此外,您可能不应该使用绑定到每个字段的模板,而是使用{{#each}}
<template name="fields">
{{#each withIndex fields}}
{{> zelle}}
{{/each}}
</template>
此处的问题是您无法控制当前正在呈现的单元格,因此您需要为每个{{#each}}
运行添加索引。这就是为什么我建议一个新的全球帮助者withIndex
:
Template.registerHelper('withIndex', function (list) {
var withIndex = _.map(list, function (v, i) {
v.index = i;
return v;
});
return withIndex;
});
您可以像使用数组中的任何其他字段一样使用新的index
。您将需要它来确定单击了哪个号码以及增加计数器的位置。我已使用td
的{{1}}值来存储点击了哪个单元格的索引。
id
答案 1 :(得分:0)
在你开始阅读之前,你应该熟悉Meteor系列,因为这是做你的例子的最佳方式,以及&#34;这个&#34;在#each循环中工作
您可以创建一个模板并将数据传递给此
<template name="zelle">
<td class="box">
<p class="textinbox">{{name}}</p>
</td>
</template>
主模板看起来像这样
<table>
{{#each zellen}}
<tr>
{{#each zellen}}
{{>zelle}}
{{/each}}
</tr>
{{/each}}
</table>
第一个#each
可以有任何其他帮助器,但是如果你想要方形,你需要通过<td>
和<tr>
我宁愿制作一个收藏来保存你的数据
在客户端,你可以做这样的事情:
yourCollection= new Meteor.Collection('yourCollection');
Meteor.startup(function(){
If(yourCollection.find().count()==0){
yourCollection.insert({name:1});
yourCollection.insert({name:2});
etc...
}
});
事件可能如下所示:
"click td": function() {
yourCollection.update({_id:this._id},{$inc:{name:1}});
}
因为你现在有一个集合zellen助手应该看起来像
zellen: function(){
return yourCollection.find();
}
答案 2 :(得分:0)
Sindis给出的答案看起来是正确的,假设您想使用集合来管理反应性。在大多数情况下,你这样做,但并不总是。我将提出一种使用scoped reactivity的替代解决方案,其中每个模板都跟踪它自己的状态,而不需要全局会话变量。警告 - 这是一个有点高级的主题。这是一个有效的解决方案:
<body>
<table>
{{#each zellen}}
{{#if newrow}}
<tr></tr>
{{/if}}
{{> zelle}}
{{/each}}
</table>
</body>
<template name="zelle">
<td class="box">
<p class="textinbox">{{counter}}</p>
</td>
</template>
if (Meteor.isClient) {
Template.body.helpers({
zellen: function() {
var rows = 3;
var columns = 4;
// dynamically build the zellen
var zellen = _.times(rows * columns, function(i) {
var newrow = false;
if ((i % columns) === 0)
newrow = true;
return {count: i + 1, newrow: newrow}
});
return zellen;
}
});
Template.zelle.created = function() {
this.counter = new ReactiveVar;
this.counter.set(this.data.count);
};
Template.zelle.helpers({
counter: function () {
return Template.instance().counter.get();
}
});
Template.zelle.events({
click: function(e, template) {
var count = template.counter.get();
template.counter.set(count + 1);
}
});
}
请注意,您需要运行meteor add reactive-var
才能生效。