Meteor: How to trigger reRun of helper function af

2019-03-29 05:00发布

问题:

This a new version of my old question:

So thanks to Tom Coleman's help I finally figured out on how to properly check if a subscription is ready() or not.

My current code structure looks like this:

/client/app.js:

eventsHandle = null;
groupsHandle = null;
// ...
// First Deps.autorun():
// Does not depend on any Session var, should just run every time
Deps.autorun(function() {
    eventsHandle = Meteor.subscribe("events", function() {
        console.log('Deps.autorun(): Events loaded');
    });
});

// Second Deps.autorun():
// contains all subscriptions which are dependent on my Session var "ehash"
Deps.autorun(function() {
    if(Session.get('ehash'))
        groupsHandle = Meteor.subscribe("groups", Session.get('ehash'), function() {
            console.log('Deps.autorun(): Groups loaded with ehash: ' + Session.get('ehash'));
        });
});
// ...

Then I have view specific .js and .html files for all the template stuff in a folder called:

/client/views/
--> <page>.js:

Template.x.dataLoaded = function() {
    if(Session.get('ehash'))
        if(eventsHandle && groupsHandle && eventsHandle.ready() && groupsHandle.ready()) {
            console.log('All data loaded!');
            singleevent = Events.find({ehash: Session.get('ehash')}).fetch()[0];
            return true;
        } 
}

This helper dataLoaded wraps basically everything in the corresponding template and shows the content when dataLoaded returns true or else shows a loading spinner.

Problem is that in many cases this does not work because this dataLoaded code is only run once. So if the two handles are NOT ready() at the time dataLoaded is run, content will NEVER show up. In this case I still see all the console.log's coming from the app.js file (the Deps.autorun() stuff) but the log "All data loaded!" is never echod.

So my question is: How do I trigger a rerun of this code so dataLoaded is run again so content will eventually show up?

best regards

回答1:

The problem can be solved simply by creating a dependency:

var _dep = new Deps.Dependency();

Template.x.dataLoaded = function() {
    _dep.depend();
    ...
}


function handler() {
    ... do.stuff();
    _dep.changed();
}

Now, every time you run _dep.changed() method, the helper will rerun. Simple!



回答2:

To call the ready() method of eventHandle you need the parentheses otherwise I think you are just checking that the ready method exists. Discussion of this is here.

This will probably still leave you with a problem if eventHandle is being set to various subscription handles in different parts of your javascript. Try structuring the files of your app as described here.



回答3:

Yes, you need to call this.ready() manually. See the example in documentation.



回答4:

This looks more complicated than it needs to be. I'm quite possibly missing something, but it seems to me you're just trying to set a loading spinner when data is loaded. I've posted a simple, more readable way of showing "loading" in Meteor.