Materialize: dropdown in “if” statement doesn't work

一曲冷凌霜 提交于 2019-11-28 01:29:28

问题


I tried to implement a dropdown list that is only visible when the user is signed in. The dropdown list works when outside the "if" statement but not inside. The buttons "Foo" and dropdown button are shown, however it doesn't "dropdown".

header.html

<!-- Header -->
<template name="header">
<nav>
    <div class="nav-wrapper">
        <a  class="brand-logo" href="{{pathFor 'home'}}">Logo</a>
        <ul id="nav-mobile" class="right hide-on-med-and-down">
            {{#if currentUser}}
                <!-- dropdown1 trigger -->
                <li>
                    <a class="dropdown-button" href="#!" data-activates="dropdown1">
                        <i class="mdi-navigation-more-vert"></i>
                    </a>
                </li>

                <li><a href="#">Foo</a></li>
            {{else}}
                <li><a href="{{pathFor 'signin'}}">Sign in</a></li>
            {{/if}}

            <li><a href="{{pathFor 'about'}}">About</a></li>
        </ul>
    </div>
</nav>

<!-- dropdown1 structure -->
<ul id="dropdown1" class="dropdown-content">
    <li class="signout"><a href="#!">Sign out</a></li>
</ul>
</template>

header.js

Template.header.rendered = function () {
    $(".dropdown-button").dropdown({
        belowOrigin: true // Displays dropdown below the button
    });
};

What could be the problem?


回答1:


When your Template.header.onRendered lifecycle event is first fired, the dropdown HTML elements are not yet inserted into the DOM because the condition {{#if currentUser}} is not yet met (it takes a small amount of time before being actually logged in a Meteor app, that's why Meteor.user being reactive is handy !).

This is why your jQuery dropdown initialization fails : the DOM is not yet ready ! The solution is quite simple thoug : refactor your Spacebars code to put the dropdown markup in its own separate template :

<template name="dropdown">
  <li>
    <a class="dropdown-button" href="#!" data-activates="dropdown1">
      <i class="mdi-navigation-more-vert"></i>
    </a>
  </li>
  <li><a href="#">Foo</a></li>
</template>

Then insert the child template inside your header template :

{{#if currentUser}}
  {{> dropdown}}
{{else}}
  {{! ... }}
{{/if}}

This way the dropdown will have its own onRendered lifecycle event that will get triggered only after the user is logged in, and at this time the dropdown DOM will be ready.

Template.dropdown.onRendered(function(){
  this.$(".dropdown-button").dropdown({
    belowOrigin: true // Displays dropdown below the button
  });
});

Sometimes refactoring your code into smaller subtasks is not just a matter of style, but it makes things work the way intended.



来源:https://stackoverflow.com/questions/29815310/materialize-dropdown-in-if-statement-doesnt-work

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