如何从Meteor多次呈现的模板中获取价值?

时间:2017-03-09 08:38:40

标签: jquery templates meteor

我希望从多次呈现的模板中获取助手内部不同的音频持续时间。除了在数据库中插入音频持续时间之外,有没有办法做到这一点?我已经尝试过很多东西,有些东西根本不推荐,而且没有一个可行。向我展示任何东西,只显示第一个音频的持续时间。这是一个丑陋的jerryrigs实际上返回一个数字,但它仍然很破碎,导致setInterval不会停止。

Meteor.myaudioplayer.helpers({
   audioduration: function(){
     //if using ReactiveVar...
    audio = $("audio").get(0);
    instance = Template.instance();

        if (!instance.audioduration.get() || isNaN(parseInt(audio.duration))) {
              audioLenght = Meteor.setInterval(function() {
                    var totaltime = parseInt(audio.duration, 10);
                    var mins = Math.floor(audio.duration / 60, 10);
                    var secs = totaltime - mins * 60;
                    var gimmethetime = mins + ':' + (secs > 9 ? secs : '0' + secs);

                    instance.audioduration.set(gimmethetime);
                    return gimmethetime;

              }, 500);
        } 

        else {
            Meteor.clearInterval(audioLenght);
            return instance.audioduration.get();
        }
      }
});

这是我的HTML,如果它有所帮助。

<div class="myplayer {{label}}>
    
    <div class=" gutter ">
	  <div class="loading">		
	  </div>
	  <div class="played"> 
	  </div>	
	  <div class="handle"> 
	  </div>
   </div>

	<div class="controls ">
	  <span class="playtoggle glyphicon glyphicon-play "></span>
		<div class="volume-control ">
		  <span class="volume glyphicon glyphicon-volume-up "></span>

			<div class="volume-gutter hidden ">
			  <div class="volume-meter ">
				 <div class="volume-handle "></div>
			  </div>
			</div>

	       </div>
			
    <span class="title">{{audioName}}</span>
    <span class="timeleft pull-right"> {{audioplayed}} / {{audioduration}}</span>
    </div>
 </div>

<audio class={{label}}>
  <source src={{mysource}} format={{myformat}}/>
</audio>

在播放器的其他部分获取当前音频位置和音频持续时间也很重要,但由于这些是由用户触发的内部事件,因此我们可以向浏览器询问元素的外观是什么使用事件目标作为参数。

EDIT 有人在“播放”按钮上询问了我的代码。这里是。我还在调整变量,所以我可以同时拥有两个播放功能,但效果很好。 注意:我更改了上面的HTML以匹配此代码,因为我在版本之间弄乱了一些类名。

"click .playtoggle": function(event) {
  thisplayer = $(event.target).parents(".audioplayer").attr("id");
  thisaudio = $("#" + thisplayer).find("audio").get(0);

  console.log(thisaudio.duration);

  //Playing
  if (!playing) {
    playing = true;
    $("#" + thisplayer).find(".playtoggle").removeClass("glyphicon-play");
    $("#" + thisplayer).find(".playtoggle").addClass("glyphicon-pause");
    thisaudio.play();

    playIt = Meteor.setInterval(function() {
      //vars for the visual aspect
      var handlepadding = parseInt($("#" + thisplayer).find(".handle").css("width")) / 2;
      var gutterwidth = $("#" + thisplayer).find(".gutter").width() - handlepadding;
      var soundcoordinates = parseInt(thisaudio.currentTime, 10);
      var totaltime = parseInt(thisaudio.duration, 10);
      var playedgutter = gutterwidth * soundcoordinates / totaltime;

      // If user is not messing with the handle, give the position
      if (!draghandle) {
        $("#" + thisplayer).find(".played").css("width", playedgutter + "px");
        $("#" + thisplayer).find(".handle").css("left", playedgutter + "px");
      }

      // If the audio has come to an end, acknowledge that it has ended
      if (soundcoordinates == totaltime) {
        playing = false;
        $("#" + thisplayer).find(".playtoggle").removeClass("glyphicon-pause");
        $("#" + thisplayer).find(".playtoggle").addClass("glyphicon-play");
        Meteor.clearInterval(playIt);

      }

      // Send the data to the timer
      instance.timeplayed.set(soundcoordinates);

    }, 500);

    return;
  }
  // END Playing

  // Pausing
  if (playing) {
    playing = false;
    $("#" + thisplayer).find(".playtoggle").removeClass("glyphicon-pause");
    $("#" + thisplayer).find(".playtoggle").addClass("glyphicon-play");
    Meteor.clearInterval(playIt);
    thisaudio.pause();
    return;
  }
//END pausing

}

2 个答案:

答案 0 :(得分:1)

HTML

<span class="timeleft pull-right"> {{audioplayed}} / <span id="duration"></span></span>

js func

function  gimmethetime(audio){
  var totaltime = parseInt(audio.duration, 10);
  var mins = Math.floor(audio.duration / 60, 10);
  var secs = totaltime - mins * 60;
  var timeLeft = mins + ':' + (secs > 9 ? secs : '0' + secs);
  $("#duration").text(timeLeft);
}

使用jQuery设置开始时间

Template.myaudioplayer.onRendered(
   function(){
        audio = $("audio").get(0);
        if (audio) {
             gimmethetime(audio);
        } 
      }
);

当用户点击播放时

 ...
 playIt = Meteor.setInterval(function() {
    gimmethetime(thisaudio);
    ....
 }
 ...

答案 1 :(得分:0)

我找到了解决我特定问题的答案。它可能不是最漂亮的东西,它不是我想要的,因为它不再使用助手了,但它有效。我不得不改变HTML,所以现在,而不是在计时器“.timeleft”范围内的两个助手(一个用于进度而另一个用于持续时间),我有两组跨度。

<span class="timeleft pull-right">
 <span class="audioplayed"></span> /<span class="audioduration"></span>
</span>

在onRendered中,我有:

      audio = $("audio").get(0);

      idArray = $(".audioplayer").map(function() {
        return this.id;
      }).get();

      if (audio.duration && !isNaN(audio.duration)) {
        Meteor.clearInterval(getDuration);
      } else {
        getDuration = Meteor.setInterval(function() {
          for (i = 0; i < idArray.length; i++) {
            var audioduration = $("#" + idArray[i]).find("audio").get(0).duration;
            var totaltime = parseInt(audioduration, 10);
            var mins = Math.floor(audioduration / 60, 10);
            var secs = totaltime - mins * 60;
            var gimmethetime = mins + ':' + (secs > 9 ? secs : '0' + secs);

            $("#" + idArray[i]).find(".audioduration").text(gimmethetime);
          }
          if (audio.duration && !isNaN(audio.duration)) {
            Meteor.clearInterval(getDuration);
          }
        }, 500);
      }

让我解释一下我的所作所为。 在 onRendered 内部,变量 audio 仅返回第一个音频文件,并以NaN形式返回,因为该元素尚未完全渲染。为了得到这两个值,我创建了一个数组,其中包含每个已经渲染的div.audioplayer的id(idArray变量看起来像这样:[label1,label2])。然后我在for循环中运行这些id以获取音频持续时间,然后在右侧元素(div#label [i]的子级)上写入。

然而,这遇到了音频变量的同样问题:模板还没有完成渲染,所以当我问我的文档这些音频有多长时间时,它不知道。我的解决方法是将我的循环放在一个setInterval中,以便它一直询问,直到它得到答案,然后停止。我可以使用音频变量进行验证,因为当它返回一个值时,很可能其他音频也会出现。现在,我有两个音频持续时间,每个音频持续时间都是该模板的相应计时器,它被渲染两次。

Template of the audioplayer rendered twice

我打算使用相同的技术更新计时器音频播放部分的音频进度。