iT邦幫忙

0

已刪文31

  • 分享至 

  • xImage

已刪文

看更多先前的討論...收起先前的討論...
淺水員 iT邦大師 6 級 ‧ 2023-08-16 14:36:40 檢舉
requestAnimationFrame 拿掉的話也會錯誤嗎?
其中的部分改成

```
function checkSelectChange() {
if (selectChanged) {
// Remove create_certain_ipc_log_table(sending_data_to_api_log_file_list);
certain_ipc_log_table.destroy();
$("#certain_ipc_log_table_example").empty();
certain_ipc_log_table = $("#certain_ipc_log_table_example").DataTable(dataToUse);
selectChanged = false; // Reset the flag to false
}
// requestAnimationFrame(checkSelectChange);
}

// requestAnimationFrame(checkSelectChange); // Start checking
```

這個function "checkSelectChange()" 同時也沒地方用了

**Uncaught RangeError: Maximum call stack size exceeded** 還是會遇到
所以不是 `if (!certain_ipc_log_table) ....... 略` 這邊 判斷式的問題嗎?
淺水員 iT邦大師 6 級 ‧ 2023-08-18 17:26:13 檢舉
因為我沒全看,不是很確定那邊到底會不會被頻繁地呼叫
如果覺得是 if 那邊的問題
我覺得可以把 dataToUse 印出來
然後把測試一下刪除其他程式碼,直接設定 dataToUse 為剛剛的資料丟給 DataTable
看看是不是 DataTable 本身的問題
淺水員 iT邦大師 6 級 ‧ 2023-08-18 17:30:44 檢舉
我只是提出
也有可能是 DataTable 本身的問題(例如資料量不能太大)
或是你 dataToUse 設定的方式不符合他要求的方式
這部分可以先確認,再來討論重複執行的問題
喔喔,知道了,感恩
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

1
熊熊工程師
iT邦研究生 2 級 ‧ 2023-08-16 18:29:47

根據你提供的程式碼,我嘗試做一些改進以避免可能導致遞迴調用的問題。請確保你在實際使用之前測試這些改進是否適用於你的情況。

$(document).ready(() => {
  const getToken = localStorage.getItem("token");
  
  // ... 其他程式碼 ...

  // 監聽下拉選單的 change 事件
  $("#exampleFormControlSelect1").change(function() {
    // ... 其他程式碼 ...

    selectedDeviceId = selectedOption.data("device_id").toString();
    sending_data_to_api_log_file_list.device_id = selectedDeviceId;

    // 更新表格
    update_certain_ipc_log_table();
  });

  // 初始化表格
  update_certain_ipc_log_table();

  // 監控變更
  function checkSelectChange() {
    if (selectChanged) {
      update_certain_ipc_log_table();
      selectChanged = false;
    }
    requestAnimationFrame(checkSelectChange);
  }

  requestAnimationFrame(checkSelectChange);

  // 更新表格
  function update_certain_ipc_log_table() {
    // 建立預設的 dataToUse 物件
    let dataToUse = {
      ...defaultData,
      ajax: {
        ...defaultData.ajax,
        data: function(data) {
          sending_data_to_api_log_file_list.search = data.search.value;
          return JSON.stringify(sending_data_to_api_log_file_list);
        },
      },
    };

    // 如果 certain_ipc_log_table 已存在,就銷毀它
    if (certain_ipc_log_table) {
      certain_ipc_log_table.destroy();
      $("#certain_ipc_log_table_example").empty();
    }

    // 創建新的表格
    certain_ipc_log_table = $("#certain_ipc_log_table_example").DataTable(dataToUse);
  }
});

這個改進的版本將初始化表格的邏輯與更新表格的邏輯分開,避免了可能的遞迴問題。在 change 事件和初始化時都調用了 update_certain_ipc_log_table 函式,確保了表格的一致性。請根據你的實際需求和代碼結構進行調整。

來自 GPT 的回答,供參考

這個好像不行捏,還是有** Uncaught RangeError: Maximum call stack size exceeded**

我是照大神說的,用update_certain_ipc_log_table函式
並把defaultData 變全域

以下是修改的代碼:


$(document).ready(() => {
    const getToken = localStorage.getItem("token");
    
    var rowData;
    var selectedDeviceId;
  
    console.trace("取得令牌", getToken);
    newValue = localStorage.getItem("newValue");
    
    var accountType = localStorage.getItem("acc_type");
    var certain_ipc_log_table ;
  
    let sending_data_to_api_log_file_list= {
        "draw": 1,
        "length": 10,
        "start": 0,
        "device_id": "",
        "search": "",
        "start_datetime": "",
        "end_datetime": ""
      }
  
      let df = {
        draw: 0,
        columns: ["device_id", "name", "group"],
      };
    
    
    $.ajax({
        type: "post",
        url: newValue + '/api/ipc/select',
        async: true,
        headers: {
            "Content-Type": "application/json",
            "accept": "application/json",
            Authorization: "Bearer " + getToken,
        },
        data: JSON.stringify(df),
        success: function (res) {
            
            console.trace('成功檢查');
            console.trace("回傳結果", res);
    
            var selectElement = document.getElementById("exampleFormControlSelect1");
    
            selectElement.innerHTML = "";
    
            var defaultOption = document.createElement("option");
            defaultOption.textContent = "Server";
            defaultOption.value = ''; // 將值設置為空字符串
            defaultOption.dataset.device_id = ''; // 將 dataset.device_id 設置為空字符串
            selectElement.appendChild(defaultOption);
    
            res.data.forEach(function (item) {
                var option = document.createElement("option");
    
                // 將選項的文本內容設置為 group、device_id 和 name 的組合
                option.textContent = item.group + " - " + item.device_id + " - " + item.name;
    
                // 將個別值存儲在後續使用的數據屬性中
                option.dataset.group = item.group;
                option.dataset.device_id = item.device_id;
                option.dataset.name = item.name;
  
                temp_device_id= item.device_id
                console.trace("item.device_id;",temp_device_id)
    
                selectElement.appendChild(option);
            });
        },
        error: function (error) {
            console.trace("錯誤", error);
        }
    });
    
    // create_certain_ipc_log_table();   // 網頁剛加載時,默認的日誌表是用於服務器的
    update_certain_ipc_log_table();
  
    // 監聽下拉選單的 change 事件
    var selectChanged = false; // 添加一個標誌來檢測下拉選單是否已更改
  
    // 監聽下拉選單的 change 事件
    
    $("#exampleFormControlSelect1").change(function() {
        // 獲取所選擇的選項元素
        var selectedOption = $(this).find(":selected");
        selectChanged = true; // 在下拉選單更改事件中將標誌設置為 true
    
        // 從所選擇的選項元素的數據集中獲取 device_id 的值
        selectedDeviceId = selectedOption.data("device_id");
    
        console.trace("選取的設備 ID:", selectedDeviceId);
        selectedDeviceId = selectedOption.data("device_id").toString(); // 轉換為字符串
  
          sending_data_to_api_log_file_list.device_id = selectedDeviceId;
    
        console.trace("更新後的 sending_data_to_api_log_file_list:", sending_data_to_api_log_file_list);
  
        certain_ipc_log_table = $("#certain_ipc_log_table_example").DataTable()
            certain_ipc_log_table.destroy();
    $("#certain_ipc_log_table_example").empty();
    
        // 調用函數以使用更新後的 sending_data_to_api_log_file_list 創建 certain_ipc_log_table
        if (selectChanged) {
            // create_certain_ipc_log_table(sending_data_to_api_log_file_list);
            update_certain_ipc_log_table(sending_data_to_api_log_file_list);
            selectChanged = false; // 重置標誌為 false
        }
    });
    
    function checkSelectChange() {
        if (selectChanged) {
            // 移除 create_certain_ipc_log_table(sending_data_to_api_log_file_list);
            certain_ipc_log_table.destroy();
            $("#certain_ipc_log_table_example").empty();
            certain_ipc_log_table = $("#certain_ipc_log_table_example").DataTable(dataToUse);
            selectChanged = false; // 重置標誌為 false
        }
        requestAnimationFrame(checkSelectChange);
    }
  
    requestAnimationFrame(checkSelectChange); // 開始檢查
    

     // 監控變更
  function checkSelectChange() {
    if (selectChanged) {
      update_certain_ipc_log_table();
      selectChanged = false;
    }
    requestAnimationFrame(checkSelectChange);
  }

  requestAnimationFrame(checkSelectChange);

  // 更新表格
  function update_certain_ipc_log_table() {
    // 建立預設的 dataToUse 物件
    let dataToUse = {
      ...defaultData,
      ajax: {
        ...defaultData.ajax,
        data: function(data) {
          sending_data_to_api_log_file_list.search = data.search.value;
          return JSON.stringify(sending_data_to_api_log_file_list);
        },
      },
    };

    // 如果 certain_ipc_log_table 已存在,就銷毀它
    if (certain_ipc_log_table) {
      certain_ipc_log_table.destroy();
      $("#certain_ipc_log_table_example").empty();
    }

    // 創建新的表格
    certain_ipc_log_table = $("#certain_ipc_log_table_example").DataTable(dataToUse);
  }
  
  });

  const getToken = localStorage.getItem("token");
    
  var rowData;
  var selectedDeviceId;

  console.trace("取得令牌", getToken);
  newValue = localStorage.getItem("newValue");

  let defaultData = {
    processing: true,
    lengthChange: true,
    serverSide: true,
    lengthMenu: [10, 100],
    bDestroy: true,

    ajax: {
        url: newValue + '/api/log/files/list',
        type: "POST",
        contentType: 'application/json',
        data: function(d) {
            d.search = d.search.value;
            console.trace(d);
            d.order_by = defaultOrder;
            d.order_column = defaultOrderColumn;
            console.trace("d.order_by", d.order_by);
            console.trace("d.order_column", d.order_column);
            return JSON.stringify(d);
        },
        headers: {
            Authorization: "Bearer " + getToken,
        }
    },

    columns: [
        { data: "filepath", title: "filepath" },
        { data: "filename", title: "filename" },
        { data: "extension", title: "extension" },
        { data: "modified", title: "modified" },
        { data: "size", title: "size" },
        {
            data: null,
            title: accountType === "OP" ? "" : "操作",
            visible: accountType !== "OP",
            render: function (data, type, row) {
                if (accountType === "OP") {
                    return "";
                } else {
                    return (
                        '<button type="button" class="btn btn-outline-light btn-edit-delete" id="Edit_Data" data-toggle="modal" data-target="#exampleModal" data-whatever="" onclick="download_certain_ipc_log_to_txt(' + selectedDeviceId + ', \'' + row.filepath + '\', \'' + row.filename + '\')">下載</button>'
                    );
                }
            },
        }
    ],

    error: function(xhr, status, error) {
        console.trace("xhr 錯誤: ", xhr.responseText);
        console.trace("狀態 錯誤: ", status);
        console.trace("錯誤 錯誤: ", error);
    }
};

我要發表回答

立即登入回答