Meteor动态创建对象并引用它们? //有一种简单的方法可以做到这一点

时间:2014-11-19 12:49:36

标签: javascript meteor expandable

所以,我对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次?或者有更有效的方法吗?

已经感谢您阅读本文!

3 个答案:

答案 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的替代解决方案,其中每个模板都跟踪它自己的状态,而不需要全局会话变量。警告 - 这是一个有点高级的主题。这是一个有效的解决方案:

app.html

<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>

app.js

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才能生效。