jquery 按钮从 AJAX 调用重新加载到页面,单击事件不起作用

4c8rllxm  于 2023-06-05  发布在  jQuery
关注(0)|答案(1)|浏览(134)

这是一个使用.NET 7的ASP.NET Core Web应用程序。我有一个创建Notes的页面,一旦创建了Notes,它就会动态地将该符号的所有Notes加载到表单下的表中。
这里是HTML部分

<section>
<div id="error-messages" class="text-danger hidden"></div>
<table id="notes-for-symbol-table"
       class="table table-bordered table-striped table-vcenter">
    <thead>
        <tr>
            <th class="text-center" style="width: 10%;">Symbol</th>
            <th class="d-none d-md-table-cell" style="width: 10%;">Date</th>
            <th class="d-none d-md-table-cell" style="width: 10%; font-size: .618em;">Author-Source</th>
            <th class="d-none d-md-table-cell" style="width: 50%;">Text</th>
            <th class="text-center" style="width: 10%;">Moves</th>
            <th class="text-center" style="width: 10%;">Actions</th>
        </tr>
    </thead>
    <tbody id="notes-for-symbol-body">
    </tbody>
</table>
</section>

这些行是通过 AJAX 调用动态生成的:

const getEquityNotesForSymbol = async function (symbol) {
    var newHtml = "";
    try {
        const responseData = await $.ajax({
            type: "GET",
            url: `${apiBaseUrl}/notes/${symbol}`,
            datatype: "json"
        });

        $.each(responseData, function (i, item) {
            newHtml = `${newHtml} <tr><td class="text-center">${item.partitionKey}
            </td><td class="fw-semibold fs-sm">${item.rowKey}
            </td><td class="d-none d-md-table-cell fs-sm">${item.noteAuthor} - ${item.noteSource}
            </td><td class="d-none d-sm-table-cell">${item.noteText}
            </td><td class="d-none d-sm-table-cell">Net: ${item.netChangeOnDayOfNote}<br />Pct:
            ${item.percentChangeOnDayOfNote}</td><td class="text-center">
            <button class="btn fas fa-edit" style="color:orange"
            onclick="editEquityNote(${item.partitionKey}, ${item.rowKey})"></button>
            <button class="btn fas fa-trash-alt" style="color:red"
            onclick="deleteEquityNote(${item.partitionKey}, ${item.rowKey})"></button>
            </td></tr>`;
        });

        const $notesTable = $("#notes-for-symbol-table > tbody");
        $notesTable.html("");
        $notesTable.html(newHtml);
       //rest removed for brevity

动态创建的编辑和删除按钮不起作用。在阅读了委托事件之后,我确信这是正常的。从我所读到的内容来看,您必须使用HTML中已经存在的父选择器,然后深入到动态创建的部分。
我不知道如何创建这种类型的委托事件处理程序。我是在按钮HTML的onclick事件中做的吗?我是否在.js文件中创建一个函数?我是jQuery和JavaScript的低端/中级用户,所以我不熟悉如何使用和创建这些委托事件处理程序。

ergxz8rk

ergxz8rk1#

Event Delegation可以在您的场景中工作,但它不会像您使用editEquityNotedeleteEquityNoteonclick处理程序那样解决使用内联函数所固有的任何问题。只要这些函数是在全局作用域中定义的,那么无论这些按钮是何时添加到DOM的,单击这些按钮时都可以访问它们。
然而,我怀疑(您已经在评论中确认了)如何将参数传递给这些内联函数调用存在问题。一个像onclick="editEquityNote(${item.partitionKey}, ${item.rowKey})"这样的模板字符串,当给定一个像{ partitionKey: 1, rowKey: 'ABC' }这样的项目时,将得到插值字符串:onclick="editEquityNote(1, ABC)"。这是无效的JavaScript,因为像ABC这样的字符串需要用引号括起来。为了获得预期的有效插值,我们需要在模板字符串中包含${item.rowKey}周围的引号:onclick="editEquityNote(${item.partitionKey}, '${item.rowKey}')"
Here是一个小提琴的例子。
这个更改应该足以让事情正常工作,但为了完整起见,我将演示如何在您的场景中使用事件委派。
您需要添加包含partitionKeyrowKey值的data-attribute,以便委托的click处理程序可以从clicked元素访问这些值。您还需要一种方法来区分编辑按钮和删除按钮,并使用jQuery选择器。我也将使用data-attributes来实现这一点:[data-edit-button]用于编辑按钮,[data-delete-button]用于删除按钮。模板的相关部分变为:

<button
  class="btn fas fa-edit"
  style="color:orange"
  data-edit-button
  data-partition-key="${item.partitionKey}"
  data-row-key="${item.rowKey}"
>Edit</button>
<button
  class="btn fas fa-trash-alt"
  style="color:red"
  data-delete-button
  data-partition-key="${item.partitionKey}"
  data-row-key="${item.rowKey}"
>Delete</button>

委托的事件处理程序需要附加到DOM中已经存在的元素,我们可以使用#notes-for-symbol-table表。处理程序为:

$('#notes-for-symbol-table').on('click', '[data-edit-button]', function () {
  const $this = $(this);
  const partitionKey = $this.data('editPartitionKey');
  const rowKey = $this.data('rowKey');
  
  alert(`edit: partitionKey = ${partitionKey}, rowKey = ${rowKey}`);
});

$('#notes-for-symbol-table').on('click', '[data-delete-button]', function () {
  const $this = $(this);
  const partitionKey = $this.data('editPartitionKey');
  const rowKey = $this.data('rowKey');
  
  alert(`delete: partitionKey = ${partitionKey}, rowKey = ${rowKey}`);
});

here在这个例子中是一个小提琴。

相关问题