Polymer: Uncaught TypeError: Cannot read property 'persistent' of undefined

Polymer: Uncaught TypeError: Cannot read property 'persistent' of undefined

当我尝试在登录页面隐藏抽屉时出现错误。我使用 dom-if 来隐藏菜单栏,根据它的 syntax 我使用了 <template> 标签。但是出现错误。

聚合物代码

<!-- Drawer content -->
<template is="dom-if" if="[[_isLogin()]]">
  <app-drawer id="drawer" slot="drawer" swipe-open="[[narrow]]">
    <app-toolbar>Menu</app-toolbar>
    <iron-selector selected="[[page]]" attr-for-selected="name" class="drawer-list" role="navigation">
      <a name="homepage" href="[[rootPath]]homepage">Homepage</a>
      <a name="profile" href="[[rootPath]]profile">Profile</a>
      <a name="temp" href="[[rootPath]]temp">Temp</a>
    </iron-selector>
  </app-drawer>
</template>

脚本

_routePageChanged(page) {
  if(this._isLogin()) {
      // If no page was found in the route data, page will be an empty string.
      // Default to 'homepage' in that case.
      this.page = page || 'homepage';

      // Close a non-persistent drawer when the page & route are changed.
      if (!this.$.drawer.persistent) {
          this.$.drawer.close();
      }
  } else {
      this.page = 'login';
  }
}

注:有_isLogin(),就是returntrue或者false

正如您在文档 here 中看到的那样,“使用数据绑定 动态 创建的节点(包括 dom-repeat 中的节点)和 dom-if 模板)未添加到 this.$ hash"

因此,由于该元素位于 dom-if 内,您将无法使用此 "shortcut" 获取对它的引用。所以你必须坚持使用 "old" getElementById,同时记住你不是在查询文档,而是查询本地影子 dom。所以这个:

  if (!this.$.drawer.persistent) {
      this.$.drawer.close();
  }

可能会变成这样:

  var drawer = this.shadowRoot.getElementById('drawer');
  if (drawer.persistent) {
    drawer.close();
  }

更新:既然你说它仍然不起作用,我想我应该提一下你需要考虑的另一件事。在您的代码中,显示该元素和查询它的条件是相同的,由 _isLogin 方法返回。

老实说,我不知道我要提出的是原因还是建议的解决方案,但我认为您应该给它时间将元素实际标记到页面中以便能够查询为此(解决单个执行线程和类似的问题)。因此,作为解决方法,您可以将代码包装在 setTimeout 回调中,如下所示:

setTimeout(() => {
  var drawer = this.shadowRoot.getElementById('drawer');
  if (drawer.persistent) {
    drawer.close();
  }
});

由于未提供第二个参数超时,您基本上是在说“尽快执行此操作,但不是现在”。