JS 實作 #4 | 建立 init() 開始程式、存放資料

原本的 code 有點雜亂,而且沒有「初始化」概念,因此我們需要建立一個 init() 函式,代表初始化這個預算小程式。

以下是原本的 code

// BUDGET CONTROLLER
var budgetController = (function(){

   // Some code

})();
// UI CONTROLLER
var UIController = (function() {

    var DOMstrings = {
        inputType: '.add__type',
        inputDescription: '.add__description',
        inputValue: '.add__value',
        inputBtn: '.add__btn'
    };

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

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

})();
// GLOBAL APP CONTROLLER
var controller = (function(budgetCtrl, UICtrl){

    var DOM = UICtrl.getDOMstrings();

    var ctrlAddItem = function() {
        // 1. Get the field input data
        var input = UICtrl.getInput();
        console.log(input);
        // 2. add the item to the budget controller
        // 3. add the item to the UI
        // 4. Calculate the budget
        // 5. Display the budget on the UI
    }

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

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

        if (event.keyCode === 13 || event.which === 13) {
            ctrlAddItem();
        }

    });

})(budgetController, UIController);

1.建立初始化 init()

首先將 eventListener 都放入 setupEventListeners(),接著 controller module 建立一個公開的 init(),在全域執行它。

// GLOBAL APP CONTROLLER
var controller = (function(budgetCtrl, UICtrl){

    **var setupEventListeners** = function() {
        var DOM = UICtrl.getDOMstrings();
        document.querySelector(DOM.inputBtn).addEventListener('click', ctrlAddItem);
        document.addEventListener('keypress', function(event) {
            if (event.keyCode === 13 || event.which === 13) {
                ctrlAddItem();
            }
        });
    };

    var ctrlAddItem = function() {
        // 1. Get the field input data
        var input = UICtrl.getInput();
        console.log(input);
        // 2. add the item to the budget controller
        // 3. add the item to the UI
        // 4. Calculate the budget
        // 5. Display the budget on the UI
    }
    
    **return {
        init: function() {
            console.log('Application has started.');
            setupEventListeners();
        }
    }**
})(budgetController, UIController);

**controller.init();**

2. 宣告 BUDGET CONTROLLER 內的資料存放方式

由於預算筆數會很多,為了讓它不散亂,可以使用 Function Constructor 構建函數建立實例的方式,再將每筆實例放進 array 裡。最後用 data 這個 object 包覆起來。

// BUDGET CONTROLLER
var budgetController = (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
        }
    };**

})();

3. 宣告完資料結構後,開始處理如何儲存每一筆輸入的資料;建立新增預算筆數的方法。

budgetController 裡面,新增一個公用方法 addItem,可以用來儲存資料進去我們設好的 data 物件中。由於原本的 data 物件裡有區分是存放 exp 或 inc 的資料,因此根據每一筆資料另外設一個主要鍵值 ID。其中,ID 的寫法必須要能判斷目前記錄的筆數為多少,所以透過**data.allItems[type][data.allItems[type].length - 1].id** 的方法,我們可以得知最新的 ID 記錄到多少,再 +1 新增即可。

// BUDGET CONTROLLER
var budgetController = (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;

            //[1, 2, 3, 4, 5],next ID = 6
            //[1, 2, 4, 6, 8],next ID = 9
            if (data.allItems[type].length > 0) {
                ID = data.allItems[type][data.allItems[type].length - 1].id + 1;
            } else {
                ID = 0;
            }

            if (type === 'inc') {
                newItem = new Income(ID, des, val);
            } else if (type === 'exp') {
                newItem = new Expense(ID, des, val);
            }

            data.allItems[type].push(newItem);

            return newItem;
        }**,
        testing: function(){
            console.log(data);
        }
    }

})();

4. 呼叫 budgetController.addItem,將 input 的值存入。

// GLOBAL APP CONTROLLER
var controller = (function(budgetCtrl, UICtrl){

    var setupEventListeners = function() {
        var DOM = UICtrl.getDOMstrings();
        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;

        // 1. Get the field input data
        input = UICtrl.getInput();
        // 2. add the item to the budget controller
        **newItem = budgetController.addItem(input.type, input.description, input.value);**
        // 3. add the item to the UI
        // 4. Calculate the budget
        // 5. Display the budget on the UI
    }
    
    return {
        init: function() {
            console.log('Application has started.');
            setupEventListeners();
        }
    }
})(budgetController, UIController);

controller.init();

Zeen is a next generation WordPress theme. It’s powerful, beautifully designed and comes with everything you need to engage your visitors and increase conversions.