迭代Meteor.js中的嵌套对象并将结果插入表中

时间:2015-03-21 19:05:19

标签: javascript object meteor html-table nested

我正在尝试在Meteor.js中制作一个RuneScape hiscores检查器。我现在已成功解析其API中的数据并将其保存为对象(您可以在此处查看应用程序:http://rs-hiscores.meteor.com/)。这是我的服务器代码:

var cheerio = Meteor.npmRequire('cheerio');

var BASE_SKILLS = [ 
  'overall', 'attack', 'defence', 'strength', 'hitpoints', 'ranged',
  'prayer', 'magic', 'cooking', 'woodcutting', 'fletching', 'fishing',
  'firemaking', 'crafting', 'smithing', 'mining', 'herblore', 'agility', 
  'thieving', 'slayer', 'farming', 'runecrafting', 'hunter', 'construction'
];

var skills = {
  'osrs': BASE_SKILLS,
  'rs3': BASE_SKILLS.concat('summoning', 'dungeoneering', 'divination')
};

var urls = {
  'osrs': 'http://services.runescape.com/m=hiscore_oldschool/index_lite.ws?player=',
  'rs3': 'http://hiscore.runescape.com/index_lite.ws?player='
};

Meteor.methods({  
  lookup: function(player, game) {
    if (!urls.hasOwnProperty(game)) {
      game = 'rs3';
    }
    var url = urls[game].concat(encodeURIComponent(player));
    result = Meteor.http.get(url);
    $ = cheerio.load(result.content);
    body = $.html();
    parsed = Meteor.call('parseStats', body, skills[game]);
    return parsed;
  },
  parseStats: function(raw, skillsList) {
    var stats = raw.split('\n').slice(0, skillsList.length);
    var statsObj = { };
    stats.forEach(function(stat, index) {
      var chunk = stat.split(',');
      statsObj[skillsList[index]] = {
        rank: +chunk[0],
        level: +chunk[1],
        xp: +chunk[2]
      };
    });
    return statsObj;
  }
});

在我的客户端代码中,我通过在函数内部提供玩家名称作为参数来手动测试查找方法:

Meteor.call('lookup', 'zezima', 'rs3', function(error, result) {

  if (error) {
    console.error(error);
  }

  console.log(result);

  Session.set("data", result);

});

Template.rawdata.helpers({

  getData: function() {
    return Session.get("data");
  }

});

控制台中的结果:

{
    agility: {
        level: 99,
        rank: 174,
        xp: 100234567
    },

    attack: {
        level: 99,
        rank: 601,
        xp: 127370193
    },

    construction: {
        level: 99,
        rank: 119,
        xp: 141170001
    },

    and so on...
}

显然,当我在html中的模板中调用getData并渲染它时,它会显示:[object Object]。所以我想以某种方式迭代对象并将它们插入到表中,这将看起来像这样:

<table id="rs-hiscores">
    <thead>
        <tr>
            <th>Skill name</th>
            <th>Rank</th>
            <th>Level</th>
            <th>Xp</th>
        </tr>
    </thead>
    <tbody id="rs-hiscore-data">
        <tr>
            <td>Agility</td>
            <td>99</td>
            <td>174</td>
            <td>109317063</td>
        </tr>
        <tr>
            <td>Attack</td>
            <td>99</td>
            <td>601</td>
            <td>127370193</td>
        </tr>
        <tr>
            <td>Construction</td>
            <td>99</td>
            <td>119</td>
            <td>141170001</td>
        </tr>

        ...and so on ...
    </tbody>
</table>

我该怎么做?而且 - 是否可以按照与BASE_SKILLS内的技能相同的顺序对结果进行排序?提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

好的,所以您需要BASE_SKILLS的顺序排列数据,使用Underscore将数据中的技能映射到新数组,{ {1}}助手应如下所示:

getData

这使得整齐的数组看起来像这样:

var data = Session.get('data');
var array = _.map( BASE_SKILLS, function(skillName){
  var skill = data[skillName]
  return {
           name: skillName,
           rank: skill.rank,
           level: skill.level,
           xp: skill.xp
         };
});
return array;

然后你需要以你想要的方式将这些值放到html中。

[
  {
    name: "overall",
    rank: 99,
    level: 174,
    xp: 109317063
  },
  {
    name: "attack",
    rank: 23,
    level: 201,
    xp: 256311563
  },
  ...etc
]

你的表中会有小写的键,<table id="rs-hiscores"> <thead> <tr> <th>Skill name</th> <th>Rank</th> <th>Level</th> <th>Xp</th> </tr> </thead> <tbody id="rs-hiscore-data"> {{#each getData}} <tr> <td>{{name}}</td> <td>{{rank}}</td> <td>{{level}}</td> <td>{{xp}}</td> </tr> {{/each}} </tbody> </table> 代替&#34;整体&#34;但是为了获得好名字,你可以制作一个字典辅助函数,将其交换为另一个,如:overall