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

喜你入骨 提交于 2019-11-29 23:15:53

问题


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}}.


回答1:


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
});


来源:https://stackoverflow.com/questions/29832371/meteor-materialize-collapsable-in-for-each-doesnt-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!