简体   繁体   中英

Meteor + Materialize: collapsable in for each doesn't work

I have a collapsable (materialize) whose elements are created from a for each , however the "dropdown" doesn't work. Everything that isn't in the for each works.

How can I fix this problem?

jobList.html

<template name="jobList">
<ul class="collapsible" data-collapsible="accordion">
    {{#each jobs}}
        <li>
            <div class="collapsible-header">{{title}}</div>
            <div class="collapsible-body"><p>{{description}}</p></div>
        </li>
    {{/each}}
</ul>

jobList.js

Template.jobList.rendered = function () {
    $('.collapsible').collapsible({
        accordion: false
    });
};

Template.jobList.helpers({
    jobs: function() {
        return Jobs.find();
    }
});

The template jobList is in another template that does nothing appart from having {{> jobList}} .

This problem is relative to DOM readiness, at the time you're executing the jQuery plugin initialization, the {{#each}} loop has not yet rendered HTML elements.

What you can do to solve this problem is defining a separate function to return the cursor you want to iterate over, and observe this cursor inside an autorun inside the onRendered callback of your template.

When we detect the cursor count is modified, it means a document has been added (in particular when the subscription is ready and the initial set of documents made their way to the client) or removed, and we have to re-run the jQuery plugin initialization.

It's important to wait for every other current invalidated computations to finish before running the jQuery initialization, this is why we need to use Tracker.afterFlush (we can't predict in which order invalidated computations are re-run, we can only execute code after this process is done).

That's because the helper returning our cursor is a computation too and will be invalidated when a document is added or removed, thus inserting or removing the corresponding DOM subset : it is then vital to execute our jQuery plugin initialization after DOM manipulation is done.

function jobsCursor(){
  return Jobs.find();
}

Template.jobsList.onRendered(function(){
  this.autorun(function(){
    // registers a dependency on the number of documents returned by the cursor
    var jobsCount = jobsCursor().count();
    // this will log 0 at first, then after the jobs publication is ready
    // it will log the total number of documents published
    console.log(jobsCount);
    // initialize the plugin only when Blaze is done with DOM manipulation
    Tracker.afterFlush(function(){
      this.$(".collapsible").collapsible({
        accordion: false
      });
    }.bind(this));
  }.bind(this));
});

Template.jobsList.helpers({
  jobs:jobsCursor
});

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