Blaze模板迭代对象

时间:2017-03-06 00:22:15

标签: javascript meteor meteor-blaze meteor-autoform

我试图在火焰模板(meteor)中迭代一个对象,在控制台中我可以看到数据,但模板上什么也没有。我怎么能让这个工作? #each不工作,arrayify也不起作用。








从评论中添加:




  {{#each contactList}}
 < tr class =“clickable”name =“edit-contact”>
 < td> {{name}}< / td>
 < td> {{email}}< / td>
 < TD> {{TITLE}}< / TD>
 < TD> {{PHONE1}}< / TD>
 < TD> {{PHONE2}}< / TD>
 < TD> {{电话3}}< / TD>
 < / TR>
 {{/每}}
  




JS:


&# xA;
  contactList:function(){
 $ .ajax({
 url:Meteor.absoluteUrl()+'contacts / get_by_company /'+ Session.get('company_id'),
 type:'GET',
错误:function(){callback();},
 success:function(res){console.log(res); return res;},
});
}
  



2 个答案:

答案 0 :(得分:2)

要回答您的主要问题,您的模板未迭代的原因是因为您的contactList函数根本没有返回任何内容。即使它确实返回了某些东西,但由于你的方法,它仍然可能不起作用。不幸的是,解决这个问题的方法不仅仅是添加一个简单的return语句,而是改变整个方法。

首先,我会高度鼓励您从头到尾阅读并关注Blaze Tutorial,然后再返回项目。 基于您共享的示例代码,很明显您误解了大多数Meteor基础知识(这是一种耻辱,因为Meteor是一个非常强大且令人愉快的框架)。希望我能帮助澄清一些事情,但在尝试跳入之前理解Meteor的工作方式绝对是必不可少的。

我在这里看到的最大问题是您正在定义API端点并从前端使用它们。虽然这在其他框架/技术中是一种相当普通的方法,但是Meteor中服务器和客户端之间的关系完全不同。事实如此不同,只有一个例子才能证明这种差异。

根据您在问题中提供的内容,我重新编写了一些内容,以解释如何在Meteor中进行此操作。

首先是模板定义(这里没有真正的变化)。

<template name="manageContacts">
  <table>
    <thead>
      <tr>
        <th>Name</th>
        <th>Email</th>
        <th>Title</th>
        <th>Phone 1</th>
        <th>Phone 2</th>
        <th>Phone 3</th>
      </tr>
    </thead>
    <tbody>
      {{#each contact in contactList}} 
      <tr class="clickable" name="edit-contact" >
        <td>{{contact.name}}</td>
        <td>{{contact.email}}</td>
        <td>{{contact.title}}</td>
        <td>{{contact.phone1}}</td>
        <td>{{contact.phone2}}</td>
        <td>{{contact.phone3}}</td>
      </tr>
      {{/each}}
    </tbody>
  </table>
</template>
然而,下一部分是完全不同的。请注意,我并不是真的建议在同一个文件中组合服务器和客户端代码,但我在这个实例中这样做是为了节省空间。

const Contacts = new Mongo.Collection('contacts');

if (Meteor.isServer) {
  Meteor.publish('contacts', function() {
    return Contacts.find();
  });
}

if (Meteor.isClient) {
  Template.manageContacts.onCreated(function() {
    Meteor.subscribe('contacts');
  });

  Template.manageContacts.helpers({
    contactList: function() {
      return Contacts.find({
        company_id: Session.get(‌​'company_id')
      });
    }  
  });
}

我们在这里发生的是创建一个联系人mongo集合,它将存储所有联系人数据。然后,我们在服务器上定义一个发布函数,将所有联系人数据发布到客户端。从客户端(例如模板),我们订阅发布(这是模板获取其数据的方式)并向返回mongo游标的模板提供帮助函数(contactList)。 Blaze当然能够迭代光标,我们所有的联系人都会在屏幕上呈现。

答案 1 :(得分:0)

您的contactList帮助器没有向您提供预期的联系人列表的直接原因是您调用异步函数($.ajax)并且之后不返回任何内容那个电话。

请参阅How do I return the response from an asynchronous call?

Meteor不知道异步调用何时完成,也不知道结果。

如果确实需要保持您的AJAX调用,您可以将结果存储在ReactiveVar中并在帮助程序中读取它。每当在辅助函数内更新被动源时,Meteor knows that it should automatically re-run your helper。因此,您的模板会在到达时自动收到结果。

import { ReactiveVar } from 'meteor/reactive-var'

var contacts = new ReactiveVar();

Template.templateName.onCreated(function () {
    $.ajax({ 
        url: Meteor.absoluteUrl()+'contacts/get_by_company/'+Session.get(‌​'company_id'),
        type: 'GET',
        error: function() { callback(); }, 
        success: function (res) {
            console.log(res);
            contacts.set(res); // Update the reactive var.
            return res; // Useless.
        }
    });
});

Template.templateName.helpers({
    contactList: function () {
        return contacts.get(); // Will get updated later on and Meteor will automatically refresh the helper.
    }
});

话虽这么说,但正如@jordanwillis所指出的,在Meteor中几乎不需要REST端点。如果您可以重新考虑检索联系人列表的方式,您可以获得更多类似Meteor的结构,具有其所有优势(实时更新,操作数据客户端的灵活性等)。