【问题标题】:How do I add an Event Listener to a Dynamic Element?如何将事件侦听器添加到动态元素?
【发布时间】:2012-10-15 12:45:25
【问题描述】:

我有以下 HTML:

<table>
    <thead>
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Description</th>
            <th>Actions</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>1</td>
            <td>Item 1</td>
            <td>Description of Item 1</td>
            <td>
                <a href="#" data-action="edit" data-item-id="1">Edit</a>
                <a href="#" data-action="delete" data-item-id="1">Delete</a>
            </td>
        </tr>
        <tr>
            <td>2</td>
            <td>Item 2</td>
            <td>Description of Item 2</td>
            <td>
                <a href="#" data-action="edit" data-item-id="2">Edit</a>
                <a href="#" data-action="delete" data-item-id="2">Delete</a>
            </td>
        </tr>
    </tbody>
</table>

动态添加表格行 (tr elements)。

我将点击事件连接到所有Edit 链接,如下所示:

void wireUpTableEvents() {
  var editLinks = queryAll('#order-items table tbody [data-action="edit"]');

  editLinks.forEach((element) {
    element.on.click.add((event){
      print(element.attributes['data-item-id']);
    });
  });
}

如上所述,表行 (tr elements) 是动态添加的,因此上述代码仅在我调用 wireUpEvents 之后我执行添加行的方法时才有效。

当将来动态添加元素时,有谁知道使用DARTon.click.add() 向元素添加事件侦听器的语法或事件侦听器?

我尝试检查 DART 文档,但 documentation on Event Listeners 为空白。

如果我使用 jQuery,我可能会使用类似于:

$("#order-items table")on("click", "tbody [data-action="edit"]", function(){...})

...但我只想使用 DART 编写我的示例应用程序。

编辑
尽管future 听起来很适合回调,但对于我需要的东西来说似乎有点矫枉过正,因为在我的场景中没有长时间运行的任务。

我能够将事件侦听器附加到静态元素但处理未来子元素的点击事件的最接近方法是:

void wireUpTableEvents() {
    var tableBody = query('#order-items table tbody');

    // Attach Event Listener to the static tbody, which always exists.
    tableBody.on.click.add((event) {
        var clickedElement = event.srcElement;
        var itemId = clickedElement.attributes['data-item-id'];

        // Check if the clicked element was either one of the edit links or one of the delete links.
        switch (clickedElement.attributes['data-action']) {
        case 'edit':
            // Replace print with calling a method to process edit request for this item.
            print('processing edit click from item with id: $itemId');
            break;
        case 'delete':
            // Replace print with calling a method to process delete request for this item.
            print('processing delete click from item with id: $itemId');
            break;
        }
    });
}​

上面的代码可以在任何实际的tr 元素加载之前执行,并且在tr 元素加载之后在某个未知的后期阶段仍然有效。

我还发现它现在涵盖了任何动态添加的行、预加载的行以及其他为新记录动态添加的行等。

【问题讨论】:

  • 我最终选择了我在问题编辑中添加的解决方案。它允许我将事件侦听器绑定到表一次,并通过使用事件冒泡和event.srcElement 属性来处理在任何阶段动态添加的任何新行中的任何点击事件。
  • 我对否决票有点困惑。无论如何,如果这个问题没有表明任何研究工作不明确或无用,请随时这样做,不要害怕让我知道如何改进它!目前,否决票看起来是随机的和荒谬的。在提出问题时,有关该主题的可用文档不存在,并且指向它的链接现在甚至完全死了。随意发表评论并附上新文档的链接,因为我很想知道该问题的另一种解决方案。

标签: dart dartium


【解决方案1】:

听起来你需要使用 Dart 的 Future 对象。 John Evans 最近有一个post,它提供了一个很好的概述。我试着举一个简单的例子:

假设我有一个名为 htmlInDart 的类,我将其调用如下:

void main() {
  var htmlExample = new HtmlInDart().createStyles();
  htmlExample
      ..then((htmlExample) => htmlExample.buildPage())
      ..then((htmlExample) => htmlExample.addListeners());
}

这个类可能看起来像这样:

class htmlInDart {

  htmlInDart();

  Future<htmlInDart> createStyles() {
    final c = new Completer();
    // create some styles
    c.complete(this);
    return c.future;
  }

  Future<htmlInDart> buildPage() {
    final c = new Completer();
    // build the page
    c.complete(this);
    return c.future;
  }

  Future<htmlInDart> addListeners() {
    final c = new Completer();
    // add some listeners
    c.complete(this);
    return c.future;
  }

希望这能让您了解如何为您的案例实施它。

【讨论】:

  • 这看起来很有希望。今晚我将阅读帖子并正确回答。我记得以前在可用的文档中遇到过future,但当时无法完全理解它。今晚我会在阅读并在我的应用中玩玩后回复更新。
  • Seth Ladd 也做了一个post 在 Dart 中使用期货,这可能会有所帮助。
  • 在玩了一会儿代码后,我还找到了另一个解决方案,这在语义上更接近我想要的。我只是将它作为对我原来问题的编辑添加,因为我不确定这在 DART 中是否可以接受(虽然它确实有效)。我发现这样做的另一个好处是,如果我通过其他操作继续添加新行,我不需要不断地向每个新行添加新的事件侦听器,并且如果重新加载表,我不需要担心关于删除/重新添加事件侦听器以防止重复的事件侦听器。
  • 很高兴您想出了一个很好的解决方案。期货对您的应用程序来说似乎有点多。无论如何,感谢您接受这个答案。
  • 您的答案似乎最适合使用 DART 功能,这就是为什么我认为这是一个很好的答案。如果我使用的解决方案实际上是我应该在 DART 中做的事情,我不确定。再次感谢您的时间和链接。您链接的两篇文章以及asynchronous programming 上的 DART 文档都非常有趣。
【解决方案2】:

当您首先添加行时,是否有任何原因无法添加回调?比如:

void addRow(TableElement table, ...) {
    TableRowElement item = new TableRowElement();

    ...

    table.nodes.add(item);
    item.on.click.add((callback) { });
}

【讨论】:

  • 感谢您的回复。我可以这样做,但不想添加一行必然负责连接事件。我宁愿把这些责任分开。目前我通过简单地调用 addRows 和wireUpEvents 来做到这一点。我只是想知道处理dynamic element 场景的 DART 方式是假设有一个场景。今晚晚些时候我正在调查Future,看看是否能解决这种情况。
猜你喜欢
  • 1970-01-01
  • 2019-10-23
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
  • 1970-01-01
  • 2012-08-17
  • 1970-01-01
  • 2022-11-24
相关资源
最近更新 更多