【问题标题】:Confused as to how the template render action is called对如何调用模板渲染操作感到困惑
【发布时间】:2014-01-09 15:37:59
【问题描述】:

我试图让播放列表中的歌曲在用户每次输入所选歌曲时出现在屏幕上。我有以下操作将他们选择的歌曲插入数据库:

 Template.search_bar.events({
'keypress #query' : function (evt,template) {
  // template data, if any, is available in 'this'
      if (evt.which === 13){
            var url = template.find('#query').value;
            $("#query").val('');
            $('#playlist_container').animate({scrollTop: $('#playlist_container')[0].scrollHeight});
            Template.list.search_get(url,0);    //insert records into the database
        }
   }

});

Template.list.search_get 将记录插入数据库:

Meteor.call('update_record',Template.list.my_playlist_id, song, function(err,message){});

在服务器端,我使用以下格式将记录推送到我的数据库中:

update_record: function(sessID, songObj){
    Links.update({sess: sessID}, {$push: {songs: {song_title: songObj["title"], videoId: songObj["video_id"], thumbnail: songObj["thumbnail"], index: songObj["index"]}}});
},

基本上我所有的记录都有以下格式:

{_id:,
 sess:, 
 songs: [{song_title:,
          videoId:,
          thumbnail:,
          index:},
         {song_title:,
          videoId:,
          thumbnail:,
          index:},...]
}

记录的歌曲字段内的歌曲对象数组。我想做的是每次用户点击搜索按钮时,让那首新歌出现在列表中。 我不确定渲染函数被调用了多少次,或者模板如何在 hmtl 中渲染数据库对象。目前我的列表有以下 html 模板:

<template name="list">
<div id="playlist_container">
  <ul id="playlist">
    {{#each my_playlist.songs}}
           {{> track}}
    {{/each}}   
 </ul>
</div>

我认为 my_playlist 应该在客户端上调用以下操作:

  Template.list.my_playlist = function(){
    console.log("myplaylist is called");
    return Links.findOne({sess: Template.list.my_playlist_id});
  }

它应该返回一个包含歌曲对象数组的对象,我在 #each my_playlist.songs 中对其进行迭代,它应该呈现以下每个轨道模板:

<template name="track">
<li id="{{index}}" class="list_element">
    <div class="destroy"> </div>
    <div class="element_style">{{song_title}}</div>
</li>
</template>

但是,在成功插入唱片后,我没有看到新歌名出现。关于我如何处理这个问题的任何建议?

【问题讨论】:

  • Template.list.my_playlist_id 是如何设置的?你确定这个值真的在改变吗?
  • 我在meteor.starup() 上设置了my_playlist_id,并在设置后立即使用playlist_id 进行订阅。

标签: mongodb templates meteor meteorite


【解决方案1】:

这段代码有问题。

Template.list.my_playlist = function(){
    return Links.findOne({sess: Template.list.my_playlist_id});
}

Template.list.my_playlist_id 永远不会更新,因此新模板永远不会呈现。

试试这个方法。

if (Meteor.isServer) {
    Meteor.methods({
        update_record: function(sessID, songObj){
            // update Links
            return Links.findOne({sess: sessID});
        }
    });
} else {
   Meteor.call('update_record',Template.list.my_playlist_id, song, function(err, song){
        Session.set('playlist', song);
    });
    Template.list.my_playlist = function(){
        return Session.get('playlist');
    }
}

【讨论】:

  • 我还应该将 Links.update 的代码放在 update_record 中吗?是什么导致新模板呈现?
  • @mlikj2006 是的,每当Session 发生变化时都会呈现新模板,因为Session 是一个反应式数据源。
  • 让我看看我是否可以直截了当,所以解决方案的要点是,每当我从客户端调用服务器以更新记录时,更新后我将歌曲对象传递回客户端(以确保它已正确添加到数据库中)。然后,我在客户端获取歌曲对象,并将其附加到会话变量中。 my_playlist 然后抓取新的会话变量,这将强制模板重新渲染。这意味着每次我按回车添加歌曲时都会调用 my_playlist 函数?
  • my_playlist 函数并非每次都执行(不是 100% 确定)。由于Session 是一个响应式数据源,Meteor 会自动将Template.list.my_playlist 同步到Session.get('playlist'); 的值
猜你喜欢
  • 1970-01-01
  • 2011-06-10
  • 1970-01-01
  • 2012-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多