提问者:小点点

JavaScript App.js:110未捕获的TypeError:无法读取未定义的属性“id”


这是我过去几周一直在做的个人项目。 但是,我在调试这个错误时遇到了麻烦:“uncatch TypeError:无法读取未定义的属性'id'”我尽力找到这个错误,但是我找不到它。 如果你能帮我解决这个问题,我将非常感激。 谢啦!

下面是我的代码:

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

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

    var data = {
        allItems: {
            exp: [],
            inc: []
        },
        totals: {
            exp: 0,
            inc: 0
        }
    };

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

            //create new ID
            if (data.allItems[type].length > 0) {
                ID = data.allItems[type][data.allItems[type].length - 1].id + 1;
            } else {
                ID = 0;
            }

            //create new item based on 'inc' or 'exp' type
            if (type === 'exp') {
                newItem = new Expense(ID, des, val);
            } else if (type === 'inc') {
                newItem = new Income(ID, des, val);
            }

            //push it into our data structure
            data.allItems[type].push(newItem);

            //return the new elelment
            return newItem; 

        },

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

})();


//UI controller
var UIController = (function () {
    
    var DOMstrings = {
        inputType: '.add__type',
        inputDescription: '.add__description',
        inputValue: '.add__value',
        inputBtn: '.add__btn',
        incomeContainer: '.income__list',
        expensesContainer: '.expenses__list'
    };
    return {
        getInput: function() {
            return {
                type: document.querySelector(DOMstrings.inputType).value, // Will be either inc or exp
                description: document.querySelector(DOMstrings.inputDescription).value,
                value: parseFloat(document.querySelector(DOMstrings.inputValue).value)
            };
        },

        addListItem: function(obj, type) {
            var html, newHtml, element;
            //HTML strings with placeholder text
            if (type === 'inc') { 
                element = DOMstrings.incomeContainer;
                html = '<div class="item clearfix" id="income-%id%"><div class="item__description">%description%</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 {
                element = DOMstrings.expensesContainer;
                html = '<div class="item clearfix" id="expense-%id%"><div class="item__description">%description%</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

            newHtml = html.replace('%id%', obj.id);
            newHtml = newHtml.replace('%description%', obj.description);
            newHtml = newHtml.replace('%value%', obj.value);
            //Insert the HTML into the DOM
            document.querySelector(element).insertAdjacentHTML('beforeend', newHtml);
        },

        getDOMstring: function () {
            return DOMstrings;
        }
    };
})();


//App contoller
var appController = (function (budgetCtrl, UICtrl) {

    var  setupEventListners = function () {
        var DOM = UICtrl.getDOMstring();
        
        document.querySelector(DOM.inputBtn).addEventListener('click', ctrlAddItem);

        document.addEventListener('keypress', function(event) {
            if (event.keyCode === 13 || event.which === 13) {
                ctrlAddItem();
            }
        });

    };

    var ctrlAddItem = function() {
        var input, newItem;
        // get input data
        input = UICtrl.getInput();
       // add the item to the budget controll
        new_item = budgetCtrl.addItem(input.type, input.description, input.value);
       // add item to theUI
        UICtrl.addListItem(newItem, input.type);
       //calculate budget
       //Display budget
       
    };

    return {
        init: function () {
            console.log('App started');
            setupEventListners();
        }
    };

})(budgetContoller, UIController);

appController.init();

共1个答案

匿名用户

将一些console.log(this)放在出现这些错误的地方。

这是因为这个未定义

您需要使用bindthis连接到函数。