【问题标题】:Meteor client-side transform collections with external data (youtube)Meteor 客户端转换集合与外部数据 (youtube)
【发布时间】:2015-06-03 06:14:26
【问题描述】:

我正在开发多租户应用程序。每个应用程序都有一个视频模块,该模块将多个 youtube 播放列表/频道 ID 作为输入。

Apps = {_id: "app01", playlists:['PL4IrNZLvgtED4RTH3xCf9085hwqKmb4lM','PLlYqpJ9JE-J8QIlua0KsBIxp-VQLyM_nO']}
Apps = {_id: "app02", playlists:['id22','id23']}

等等。

当用户重定向到地址 localhost:3000/app/:_id 时,应用订阅 Meteor.subscribe('apps',_id)。

现在在客户端,我需要渲染一个显示播放列表列表(或频道列表)的页面,其中包含播放列表的名称、播放列表缩略图;然后如果用户点击名称/缩略图,它会显示另一个页面,其中包含属于该播放列表/频道的视频列表。

我正在做的是有一个助手来检索所有 youtube 播放列表的信息:

Template.Videos.helpers({
  myPlaylist:function(){
      return Apps.findOne({}, {
            transform: function (doc){              
                playlists = doc.playlists;
                doc.date = new Date(); //for testing
                doc.videos = [];
                for (var i=0;i<playlists.length;i++){
                      console.log('find playlist: ',playlists[i]);
                      var url = 'https://gdata.youtube.com/feeds/api/playlists/'+playlists[i]+'?v=2&alt=json';
                      $.getJSON(url, function(response){
                        var video={};
                        video._id = response.feed.yt$playlistId.$t;                     
                        video.title = response.feed.title;
                        video.entry = response.feed.entry;
                        videos.push(video); 
                      })//end getJSON
                    }//end for
                doc.videos = videos;
                console.log('Result:', doc);
                return doc;
            }
        });
    }       
});

问题出在我的模板中,我可以看到 myPlaylist.date 作为转换的结果,但我看不到 myPlaylist.videos(虽然我看到 console.log 结果有数据)

有人知道如何解决这个问题吗?非常感谢!

【问题讨论】:

  • 您确定您收到来自 console.log('Result:', doc) 的响应吗?因为 $.getJSON 函数是异步的,不应该及时返回以获得可用的值。

标签: meteor youtube transform


【解决方案1】:

正如@Ian Jones 评论的那样,$.getJSON 是异步的,所以doc.videos 永远不会在您放置console.log 的地方有值。要解决这个问题,请使用ReactiveVar package

Template.Videos.onCreated(function() {
  this.videos = new ReactiveVar([]);
  var self = this;
  Apps.findOne({}, {
            transform: function (doc){              
                playlists = doc.playlists;
                for (var i=0;i<playlists.length;i++){
                      console.log('find playlist: ',playlists[i]);
                      var url = 'https://gdata.youtube.com/feeds/api/playlists/'+playlists[i]+'?v=2&alt=json';
                      $.getJSON(url, function(response){
                        var video={};
                        video._id = response.feed.yt$playlistId.$t;                     
                        video.title = response.feed.title;
                        video.entry = response.feed.entry;
                        var videos = self.videos.get();
                        videos.push(video);
                        self.videos.set(videos);
                      })//end getJSON
                    }//end for
            }
        });
    }
});
Template.Videos.helpers({
  myPlaylist:function(){
      var instance = Template.instance();
      return instance.videos.get();
  }
});

【讨论】:

  • @Ian &Geoffrey,我只需对代码稍作修改就可以看到 console.log(更改为 var temp = Apps.find(...transform()...);跨度>
  • 我没有足够的声望来投票给你的答案,我会尽可能地投票!
【解决方案2】:

感谢您的所有帮助。我从一开始就不愿意做反应变量,但你的回答激励我去做,非常感谢。 这是我的最终代码:

Template.Videos.created = function(){
  var instance = this;
  instance.videos = new ReactiveVar([]);
  instance.autorun(function(){
     MenusList.findOne({}, {
            transform: function (doc){  
                playlists = doc.playlists;
                for (var i=0;i<playlists.length;i++){
                      console.log('find playlist: ',playlists[i]);
                      var url = 'https://gdata.youtube.com/feeds/api/playlists/'+playlists[i]+'?v=2&alt=json';
                      $.getJSON(url, function(response){
                        var video={};
                        video._id = response.feed.yt$playlistId.$t;                     
                        video.title = response.feed.title;
                        video.entry = response.feed.entry;
                        var videos = instance.videos.get();
                        videos.push(video);
                        instance.videos.set(videos);
                      })//end getJSON
                    }//end for
                return doc;    
            }//end transform
        });//end findOne
  });//end autorun
}

Template.Videos.helpers({
  myPlaylist:function(){
      var instance = Template.instance();          
      return instance.videos.get();
  }
});

【讨论】:

    猜你喜欢
    • 2013-05-27
    • 2014-09-09
    • 2016-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-03
    • 1970-01-01
    相关资源
    最近更新 更多