从Session转换为ReactiveVar或ReactiveDict(Meteor)

时间:2016-11-16 15:04:58

标签: session meteor

所以,我正在制作一个音频播放器,我有一些代码来获取所选文件的音频持续时间,用于定时器。它在Session上运行得非常好,但是,因为我可能想要每页不止一个播放器,所以我决定切换到ReactiveVar或ReactiveDict,我认为我没有完全掌握它们是如何工作的,因为我的代码坏了。你能帮助我吗?我做错了什么?

这是Session的代码。

Template.audioplayer.onRendered(
  function() {
    audio = $("audio").get(0);
  }
);

Template.audioplayer.helpers({
  audioduration: function() {
    if (!Session.get("audioduration")) {
      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);

        Session.set("audioduration", gimmethetime);
        return Session.get("audioduration");

      }, 500);
    } else {
      Meteor.clearInterval(audioLenght);
      return Session.get("audioduration");
    }
  }

});

这是我最近尝试使用ReactiveVar的相同结果。它出现了“TypeError:无法读取属性'获取'未定义”。

Template.audioplayer.onCreated(
  function() {
    audio = $("audio").get(0);

    this.audioduration = new ReactiveVar();

  }
);

Template.audioplayer.helpers({
  audioduration: function() {
    if (!Template.audioduration.get()) {
      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);

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

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

});

提前致谢!

1 个答案:

答案 0 :(得分:0)

我会在回答你的问题之前添加一些信息。我已经在Internet上看到了很多使用Session变量存储临时数据的资源,这让我感到震惊。您必须了解会话生命周期在您加载页面时开始,在您重新加载页面或关闭浏览器时结束。假设您将所有临时数据存储在会话中,如果我花时间完成所有应用程序,那么我的会话将使用来自所有这些页面的数据进行调查。你没有错,我只是想在此添加一些信息。如果我错了,任何人都会纠正我。

现在是回答的地方。

在你的助手中,你有一个测试。在此测试中,您尝试使用Template.audioduration访问reactiveVar。但正如你已经为所有其他电话做的那样,它应该是Template.instance().audioduration.get()

Template.audioplayer.onCreated(
  function() {
    audio = $("audio").get(0);

    this.audioduration = new ReactiveVar();

  }
);

Template.audioplayer.helpers({
  audioduration: function() {
    if (!Template.instance().audioduration.get()) {
      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);

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

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

像这样它应该有用......

编辑:

你有第二个错误,我把它放在这里供以后参考和解释。

“setInterval回调中的异常:TypeError:无法读取null的属性'audioduration'”。为了纠正它,我告诉你使用Template.instance()在辅助作用域中创建一个变量。

这是一个典型的JS错误。在JS中,所有的难点都是了解函数的范围。在这种情况下,可以访问帮助程序中的Template变量,但无法在回调中访问它。如果您在帮助程序的上下文中引用模板实例,则可以从回调中访问它。我不太了解在这种特殊情况下如何链接不同的上下文。但通常回调无法访问this对象,我们被迫使用var that = this;。 `See this post