如何查询 dom-repeat 中的元素

How to query for an element inside a dom-repeat

我一直在网上搜索关于如何从 Dart 代码查询由 dom-repeat 元素生成的元素的明确答案。

sample.html

<dom-module id="so-sample>
  <style>...</style>
<template>
  <template is="dom-repeat" items="[[cars]] as="car>
    ...
    <paper-button on-click="buttonClicked">Button</paper-button>

    <paper-dialog id="dialog">
      <h2>Title</h2>
    </paper-dialog>
  </template>
</template>

sample.dart

我将在这里省略样板代码,例如导入或查询我的数据库以填充 cars 属性 ;一切正常。

...
@reflectable
void buttonClicked(e, [_])
{
  PaperDialog infos = this.shadowRoot.querySelector("#dialog");

  infos.open();
}

这会产生以下错误: Uncaught TypeError: Cannot read property 'querySelector' of undefined

我已经尝试了几个 'solutions',但都不行,因为没有任何效果。 我在很多线程上看到的唯一一件事是使用 Timer.run() 并在回调中编写我的代码,但这似乎是一种 hack。为什么我需要计时器?

我理解我的问题可能是 dom-repeat 的内容是懒生成的,我查询的项目 'before' 它们被添加到本地 DOM.

我没有遵循的另一个建议是使用 Mutation Observers。我在 polymer API 文档中读到应该改用 observeNodes 方法,因为它在内部使用 MO 来处理元素索引,但是打开一个对话框似乎又有点复杂。

我最后的 objective 是将每个生成模型的按钮绑定到一个专用的纸质对话框,以显示有关该项目的附加信息。 有没有人这样做过? (我希望如此 :p)

感谢您的宝贵时间!

更新 1:

阅读 Gunter 的建议后,虽然 none 他们实际上自己工作,但 ID 没有在 dom-repeat 中被破坏的事实让我思考和查询 paper-dialog 而不是 id 本身,现在弹出我的对话框!

sample.dart:

PaperDialog infos = Polymer.dom(root).querySelector("paper-dialog");

infos.open();

我现在希望每个按钮都能调用关联的对话框,因为我会在对话框内绑定与我单击的项目相关的数据 ~

更新二:

所以,不,数据绑定没有按预期工作:正如我担心的那样,所有按钮都绑定到索引 0 处的项目。我尝试了几种方法来查询正确的 paper-dialog 但没有任何效果。我发现的唯一 'workaround' 是将所有 paper-dialog 查询到一个列表中,然后从该列表中获取 'index-th' 元素。

@reflectable
void buttonClicked(e, [_])
{
  var model = new DomRepeatModel.fromEvent(e);
  List<PaperDialog> dialogs = Polymer.dom(this.root).querySelectorAll("paper-dialog");
  dialogs[model.index].open();
}

这段代码确实有效,但是获取所有元素感觉有点浪费资源,因为您实际上只需要一个元素,而且您已经知道是哪个元素。

是的,我最初的问题已经解决,但我仍然想知道为什么我不能从他们的 id 查询对话框:

...
<paper-dialog id="dialog-[[index]]">
...
</paper-dialog>
@reflectable
void buttonClicked(e, [_])
{
  var model = new DomRepeatModel.fromEvent(e);
  PaperDialog dialog = Polymer.dom(this.root).querySelector("dialog-${model.index}");
  dialog.open();
}

使用此代码,dialog 始终为 null,尽管我可以在 DOM 树中找到那些正确标识的对话框。

您需要使用 Polymers DOM API 和 shady DOM(默认)。如果您启用影子 DOM,您的代码可能也能正常工作。

PaperDialog infos = new Polymer.dom(this).querySelector("#dialog")