简体   繁体   中英

Meteor: Rerun code when template variable changes

I created a template, an audioplayer-element. The id of the audio-file is passed to the element via a template-variable. Something like this:

{{>audioPlayer audio=audio}}

The containing template is used for subsequent pages so the audioPlayer doesn't get rerendered, only the content of the pages change (like having page/1, page/2, page/3 with on every page this element on the same place). What I want to do now is load the correct file, matching the id of the variable passed. I do this with howler, and I need a subscription to get the url of the file related to the id.

Template.audioPlayer.created = function () {

    var audioId = this.data.audio;
    var subscription = this.subscribe('audio', audioId); //this is where the variable is

    if (subscription.ready()) {
        var audioUrl = Audio.findOne(audioId).url;
        var audio = new Howl({
            urls: [audioUrl]
        })
    }
}

Because this is the created-function this is only run once, but I want to have it run every time I go to a new page, to make sure I have the correct audio file matching to the right page.

I've tried wrapping this piece in a Tracker.autorun but that doesn't seem to solve the problem. It doesn't react on a change of the this.data.audio-variable. The variable itself does change, at least it does when I put this variable in a helper and display it.

Any ideas?

Right now, audioId isn't reactive. You'll need to change that to a Session var, or (even better) a query parameter in the url. I'll assume you know how to do this.

OK, now that we have a reactive variable, we need to rerun a block of code every time that variable changes. Let's use an autorun.

As you have it, that block of code is a subscription, but it only returns 1 result & chances are that url isn't going to change while someone is listening to their tunes. That's a sad, sorry subscription. What would be better is if you had a method that grabbed only the url from the server.

Tracker.autorun(function() {
  var audioId = Session.get('audioId');
  Meteor.call('getAudioUrl', function(err,res) {
    if (err) throw err;
    var audio = new Howl({
      urls: [res]
    })
  })
});

//in the server folder
Meteor.methods({
  'getAudioUrl': function(audioId) {
    return Audio.findOne(audioId).url;
  }
});

Boom. No useless subs & all the reactivity you can shake a stick at.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM