簡體   English   中英

從JSON讀取文件並循環遍歷時,最后一個值(而不是for循環中的每個迭代值)被打印

[英]Last value gets printed instead of each iteration value in for loop while reading file from JSON and looping through it

在下面的示例中,我們從JSON數據讀取並將其存儲在變量中。 然后,我們遍歷它以打印出每個迭代的值。

我有“ cartList.innerHTML”,它將列出“編輯” 4次,因為這是數組中對象的數量。 像下面

編輯

編輯

編輯

編輯

單擊第一個“編輯”后,模態應打開並顯示第一個對象的名稱,單擊第二個編輯,則第二個的名稱以此類推。

但是由於某種原因,該值仍然是每個Edit的最后一個對象的名稱。 如何獲得為每次編輯打印正確名稱的信息。

// Fetch JSON data
function loadJSON(file, callback) {
    var xobj = new XMLHttpRequest();
    xobj.overrideMimeType("application/json");
    xobj.open('GET', file, true); // Refers to JSON file
    xobj.onreadystatechange = function() {
        if (xobj.readyState == 4 && xobj.status == "200") {
            callback(xobj.responseText);
        }
    }
    xobj.send(null);
}

function load() {
    loadJSON("assets/cart.json", function(response) {
        var actual_JSON = JSON.parse(response);
        console.log(actual_JSON);

        var cartList = document.getElementById("cart-products");
        var itemObj = actual_JSON.productsInCart;       
        var itemLength = actual_JSON.productsInCart.length;

        // Loop through JSON data
        for (var i = 0; i < itemLength; i++) {

            (function(i) {
                /* Output Link Element with Edit text & on click
                   display a modal containing current value of iteration */

                cartList.innerHTML += '<div>'+
                                      '<a href="javascript: void(0);" class="btn btn-outline button-edit" data-toggle="modal" data-target=".bs-example-modal-lg">Edit</a>'+
                                      '</div>';

                var editCartModal = document.getElementById("edit-cart");
                editCartModal.innerHTML = itemObj[i].p_name;// Name of the current object

            })(i);              

        // for loop ends here
        }

    })
}
load(); // Loads function on page load

這是因為盡管您正在IIFE中運行以下代碼:

var editCartModal = document.getElementById("edit-cart");
editCartModal.innerHTML = itemObj[i].p_name;// Name of the current object

您只是修改了相同的模態( getElementById() )四次。

解決此問題的簡單答案是添加data屬性:

for (var i = 0; i < itemLength; i++) {

    (function(i) {
         /* Output Link Element with Edit text & on click
            display a modal containing current value of iteration */

        cartList.innerHTML += '<div>'+
                              '<a href="javascript: void(0);"' +  
                                  'class="btn btn-outline button-edit" data-toggle="modal"' + 
                                  'data-target=".bs-example-modal-lg" data-custom-value="' + i + 
                                  '">Edit</a>'+
                              '</div>';
    })(i);              

    // for loop ends here
}

/* ES5 way*/
/*
var list = document.getElementsByClassName('button-edit');
list.forEach(function(){
    ...
})
*/

[...document.getElementsByClassName('button-edit')].map(function(element){
    element.addEventListener('click', function(e){
        var chosenIdx = this.dataset.customValue;
        var editCartModal = document.getElementById("edit-cart");
        editCartModal.innerHTML = itemObj[chosenIdx].p_name;// Name of the current object
    }, false);
});

這是因為for循環內的每個函數在循環結束后開始執行。 這與回調相同。 當您調用每個(function(i) {})(i)它們都轉到函數調用堆棧的末尾,只有在循環的最后一次迭代之后,它們才開始執行(帶有最后一個i值)。

我很好奇為什么您根本需要一個內部內聯函數? 為什么不直接將此代碼直接放入循環主體?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM