函数未执行-JS Budget App

时间:2019-08-06 15:04:46

标签: javascript html

我出于学习目的而构建了一个预算跟踪器应用程序,并且在尝试更新DOM中的某些标签时,我注意到未执行函数nodeListForEach。

我插入了一些控制台记录的字符串来大致“调试”我的代码,但我总是得到“交叉线289”,而不是“测试”(在我需要执行的函数内部)。 。很抱歉有大量代码,但是我不明白是什么导致了错误以及在哪里。

// BUDGET
var budgetController = (function () {

    var Expense = function (id, description, value) {
        this.id = id;
        this.description = description;
        this.value = value;
        this.percentage = -1;
    };

    Expense.prototype.calcPercentage = function (totalIncome) {
        if (totalIncome > 0) {
            this.percentage = Math.round((this.value / totalIncome) * 100);
        } else {
            this.percentage = -1;
        }
    };

    Expense.prototype.getPercentage = function () {
        return this.percentage;
    }

    var Income = function (id, description, value) {
        this.id = id;
        this.description = description;
        this.value = value;
    };

    var calculateTotal = function (type) {
        var sum = 0;

        data.allItems[type].forEach(function (cur) {
            sum += cur.value;
        });

        data.totals[type] = sum;
    };


    var data = {
        allItems: {
            exp: [],
            inc: []
        },
        totals: {
            exp: 0,
            inc: 0
        },
        budget: 0,
        percentage: -1
    };

    return {
        addItem: function (type, des, val) {
            var newItem, id;

            function newID(lenght) {
                var result = '';
                var prefix = '';
                var characters = 'ABCDEFGHIJKLMOPQRSTUWXYZ0123456789';
                var charactersLength = characters.length;
                for (var i = 0; i < lenght; i++) {
                    result += characters.charAt(Math.floor(Math.random() * charactersLength));
                }

                if (type === "inc") {
                    prefix = "I-"
                } else {
                    prefix = "E-"
                }

                return prefix + result;
            }

            // Generating a New Unique ID
            id = newID(5);


            // Checking for Type
            if (type === "exp") {
                newItem = new Expense(id, des, val);
            } else if (type === "inc") {
                newItem = new Income(id, des, val);
            }

            // Pushing Into Data Structure
            data.allItems[type].push(newItem);

            // Returning New Element
            return newItem;
        },

        deleteItem: function (type, id) {
            var ids, index, newType;

            // id = 6
            // ids = [1, 2, 3, 7, 6]
            // index = 4

            var ids = data.allItems[type].map(function (current) {
                return current.id;
            });

            if (type === "inc") {
                newType = "I-";
            } else if (type === "exp") {
                newType = "E-";
            } else {
                console.log("Type Conversion Error");
            }

            index = ids.indexOf(newType + id);


            console.log(index);

            if (index !== -1) {
                data.allItems[type].splice(index, 1);
                console.log("Item Successfully Deleted");
            } else {
                console.log("Errror Occured");
            }


        },

        calculateBudget: function () {

            // A > Calculate Total Income & Expenses
            calculateTotal("exp");
            calculateTotal("inc");

            // B > Calculate Budget = income - expenses
            data.budget = data.totals.inc - data.totals.exp;

            if (data.totals.inc > 0) {
                // C > Calculate Percentage of Income we Spent
                data.percentage = Math.round((data.totals.exp * 100) / data.totals.inc);
            } else {
                data.percentage = -1;
            }



        },

        calculatePercentages: function () {

            data.allItems.exp.forEach(function (cur) {
                cur.calcPercentage(data.totals.inc);
            });

        },

        getPercentages: function () {
            var allPercentages = data.allItems.exp.map(function (cur) {
                console.log(cur.getPercentage());
                return cur.getPercentage();

            });

            return allPercentages;
        },

        getBudget: function () {
            return {
                budget: data.budget,
                totalIncome: data.totals.inc,
                totalExpenses: data.totals.exp,
                percentage: data.percentage
            }
        },

        testing: function () {
            console.log(data);
        }


    }

})();

// USER INTERFACE
var UIController = (function () {

    var DOMstrings = {
        inputType: ".add__type",
        inputDesc: ".add__description",
        inputValue: ".add__value",
        inputBtn: ".add__btn",
        incomeContainer: ".income__list",
        expensesContainer: ".expenses__list",
        container: ".container",
        expensesPercLabel: ".item__percentage"
    }




    return {
        getInput: function () {
            return {
                type: document.querySelector(DOMstrings.inputType).value, // inc or exp
                description: document.querySelector(DOMstrings.inputDesc).value,
                value: parseFloat(document.querySelector(DOMstrings.inputValue).value)
            };
        },


        addListItem: function (obj, type) {
            var html, newHtml, element;
            // Create HTML string with placeholder text

            if (type === 'inc') {
                element = DOMstrings.incomeContainer;

                html = '<div class="item clearfix" id="%id%"> <div class="item__description">%description%</div><div class="item__id"> %id% </div><div class="right clearfix"><div class="item__value">+ €%value%</div><div class="item__delete"><button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button></div></div></div>';
            } else if (type === 'exp') {
                element = DOMstrings.expensesContainer;

                html = '<div class="item clearfix" id="%id%"><div class="item__description">%description%</div><div class="item__id"> %id% </div><div class="right clearfix"><div class="item__value">- €%value%</div><div class="item__percentage">21%</div><div class="item__delete"><button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button></div></div></div>';
            }

            // Replace the placeholder text with some actual data
            newHtml = html.replace('%id%', obj.id);
            newHtml = newHtml.replace('%id%', obj.id);
            newHtml = newHtml.replace('%description%', obj.description);
            newHtml = newHtml.replace('%description%', obj.description);
            newHtml = newHtml.replace('%value%', obj.value.toFixed(2));

            // Insert the HTML into the DOM
            document.querySelector(element).insertAdjacentHTML('beforeend', newHtml);
        },

        deleteListItem: function (selectorID) {
            var el = document.getElementById(selectorID);
            el.parentNode.removeChild(el);
        },

        clearFields: function () {
            var fields;

            fields = document.querySelectorAll(DOMstrings.inputDesc + ", " + DOMstrings.inputValue);

            var fieldsArray = Array.prototype.slice.call(fields);

            fieldsArray.forEach(function (current, index, array) {
                current.value = "";
            });

            fieldsArray[0].focus();
        },

        displayBudget: function (data) {
            if (data.budget > 0) {
                document.querySelector(".budget__value").textContent = "+ €" + data.budget.toFixed(2);
            } else if (data.budget < 0) {
                document.querySelector(".budget__value").textContent = "- €" + data.budget.toFixed(2);
            } else {
                document.querySelector(".budget__value").textContent = "€" + data.budget.toFixed(2);
            }

            document.querySelector(".budget__income--value").textContent = "+ €" + data.totalIncome.toFixed(2);
            document.querySelector(".budget__expenses--value").textContent = "- €" + data.totalExpenses.toFixed(2);

            if (data.percentage <= 0) {
                document.getElementById("in%").innerHTML = "&nbsp;";
                document.getElementById("in%").classList.add("budget__income--percentage");
                document.getElementById("in%").classList.remove("budget__expenses--percentage");
            } else {
                document.getElementById("in%").classList.add("budget__expenses--percentage");
                document.querySelector(".budget__expenses--percentage").textContent = data.percentage + "%";
            }
        },

        displayPercentages: function (percentages) {

            var fields = document.querySelectorAll(DOMstrings.expensesPercLabel);

            var nodeListForEach = function (list, callback) {

                for (var i = 0; i < list.lenght; i++) {
                    callback(list[i], i);
                }

            };


            console.log("Crossed line 289...");
            nodeListForEach(fields, function (current, index) {

                console.log("Test");
                current.textContent = percentages[index] + "%";

            });

        },

        getDOMstrings: function () {
            return DOMstrings
        },

        displayMonth: function () {
            var d = new Date();
            var month = new Array();
            month[0] = "January";
            month[1] = "February";
            month[2] = "March";
            month[3] = "April";
            month[4] = "May";
            month[5] = "June";
            month[6] = "July";
            month[7] = "August";
            month[8] = "September";
            month[9] = "October";
            month[10] = "November";
            month[11] = "December";
            var n = month[d.getMonth()];
            document.querySelector(".budget__title--month").textContent = n;
        }


    }

})();

// CONTROLLER
var appController = (function (budgetCtrl, UICtrl) {

    // Setting Up All Event Listeners
    var setupEventListeners = function () {

        var DOM = UICtrl.getDOMstrings();

        document.querySelector(DOM.inputBtn).addEventListener("click", ctrlAddItem);

        document.addEventListener("keypress", function (event) {

            // Checking for the enter key pressed
            if (event.keyCode === 13 || event.wich === 13) {
                ctrlAddItem();
            }
        });

        document.querySelector(DOM.container).addEventListener("click", ctrlDeleteItem);

    };

    var updatePercentages = function () {
        var percentages;

        // A > Calculate Percentages
        budgetCtrl.calculatePercentages();

        // B > Read Percentages from Budet Controller
        percentages = budgetCtrl.getPercentages();

        console.log("Got Here...");
        // C > Update the UI with new Percentages
        UICtrl.displayPercentages(percentages);
    };

    var updateBudget = function () {
        // D > Calculate Budget
        budgetController.calculateBudget();

        // D.1 > Return Budget
        var data = budgetController.getBudget();

        // E > Display Budget in UI
        UICtrl.displayBudget(data);

    };


    var ctrlAddItem = function () {
        var input, newItem;

        // A > Get the input field data
        input = UIController.getInput();

        if (input.description !== "" && !isNaN(input.value) && input.value > 0) {
            // B > Add the item to budget controller module
            newItem = budgetCtrl.addItem(input.type, input.description, input.value);

            // C > Add item to UI
            UICtrl.addListItem(newItem, input.type);
            console.log(newItem);

            // C.1 > Clear All Fields
            UICtrl.clearFields();

            // Recalling Budget Functions...
            updateBudget();

            // Calculate and Update Percentages
            updatePercentages();
        }
    };

    var ctrlDeleteItem = function (event) {
        var itemID, splitID, type, ID;

        itemID = event.target.parentNode.parentNode.parentNode.parentNode.id;

        if (itemID) {

            // Splitting differents parts of ID
            splitID = itemID.split("-");
            console.log("SplitID > " + splitID);
            type = splitID[0];
            ID = splitID[1];

            if (type === "I") {
                type = "inc";
            } else if (type === "E") {
                type = "exp";
            }

            // A > Delete Item from Data Sructure
            budgetCtrl.deleteItem(type, ID);

            // B > Delete Item from UI
            UICtrl.deleteListItem(itemID);

            // C > Update and Show the new Budget
            updateBudget();
        }
    };

    return {
        init: function () {
            console.log("Application has started...");
            setupEventListeners();
            UICtrl.displayBudget({
                budget: 0,
                totalIncome: 0,
                totalExpenses: 0,
                percentage: 0
            });
            UICtrl.displayMonth();
        }
    }

})(budgetController, UIController);

// INIT FUNCTION RECALL > STARTING THE APPLICATION
appController.init();

1 个答案:

答案 0 :(得分:0)

一个:如果您不打算为每个函数更改函数节点列表,那么我将使用const而不是变量。这样您的代码将更加干净。 二:看起来像您的问题在281行中的for块定义中,看起来像是您拼错了长度