Meteor中意外的附加函数调用

时间:2015-03-01 20:26:13

标签: meteor

以下是演示此问题的模板。 randomArtist是一个从mongodb返回文档的函数。每次我使用该文档中的不同字段时,我都会调用该函数3次。

<template name="featuredArtist">
    <p>{{randomArtist.artistName}}</p>
    <p>{{randomArtist.description}}</p>
    <p>{{randomArtist.randId}}</p>
</template>

这是一个模板逻辑。 在服务器启动时,我使用一些数据初始化集合,因此应该(我认为)从一开始就可用于View部分。 在客户端上,我得到一个随机文档,然后在会话中存储其id(randId)以在下一个函数调用期间跳过抽奖。 (PS。这不是关键,但欢迎任何改进建议,我是Meteor的初学者。)

Artists = new Mongo.Collection("artists");

if (Meteor.isServer) {
    Meteor.startup(function () {
        Artists.insert({ randId: 0, artistName: "Artis Name 1", image: "url", description: "Description of Artis Name 1"});
        Artists.insert({ randId: 1, artistName: "Artis Name 2", image: "url", description: "Description of Artis Name 2" });
        Artists.insert({ randId: 2, artistName: "Artis Name 3", image: "url", description: "Description of Artis Name 3" });
        Artists.insert({ randId: 3, artistName: "Artis Name 4", image: "url", description: "Description of Artis Name 4" });
        Artists.insert({ randId: 4, artistName: "Artis Name 5", image: "url", description: "Description of Artis Name 5" });
    });
}
if (Meteor.isClient) {
    Meteor.subscribe("artists");

    Template.featuredArtist.helpers({
        randomArtist: function(){
            var randId = Session.get("artistRandId");
            if(!randId){
                var rand = (Artists.find().count() * Math.random()) | 0;
                var artist = Artists.findOne({randId:{$lte:rand}}, {sort: {randId: -1}});
                if (!artist) {
                    artist = Artists.findOne( { randId : { $gte : rand } } );
                }
                if (!artist) {
                    console.log('Mongo.Artists is empty');
                } 
                else {
                    console.log(artist);
                    Session.set("artistRandId", artist.randId);
                    return artist;
                }
            }
            else {
                console.log('randId='+randId);
                return Artists.findOne( { randId: randId } );
            }            
        }
    });
}

工作演示在http://meteorpad.com/pad/MhwXS6MpXQoTYh4Lw/Artists

我在日志中观察到的是'randomArtist'函数调用7(!)次而不是预期的3次,因为它在模板中被调用:

  • 3次与预期0: console.log('Mongo.Artists为空');
  • 预期的一次: console.log(艺术家);
  • 3倍与预期2: console.log('randId ='+ randId);

可以解释一下这些额外的电话来自哪里? 在我的真实应用程序中,我可以观察到更多的调用 - 可能是因为我使用了更复杂的模板,这意味着featureArtist被嵌入到另一个调用中。

目前还不清楚在日志中我怎么可能看到该集合是空的,因为它似乎在启动时填充?

1 个答案:

答案 0 :(得分:1)

我无法解释为什么你的助手被正确调用了7次,但你可以通过使用这样的#with块助手来解决它:

<template name="featuredArtist">
    {{#with randomArtist}}
        <p>{{artistName}}</p>
        <p>{{description}}</p>
        <p>{{randId}}</p>
    {{else}}
        <p>Got no random artist :(</p>
    {{/with}}
</template>

并从帮助程序中删除artistRandId会话。您的助手现在可能会被调用2次,因为模板可能会在客户端从艺术家订阅接收艺术家之前呈现(第二次在客户收到艺术家时发生)。