在原型方法调用中迷失

时间:2017-07-27 14:04:15

标签: javascript oop prototype this

道歉我意识到还有很多其他线程描述了类似的问题,但我找不到能够完全回答我问题的线索(至少以我理解的方式)。

我使用以下代码创建一个Object,用于管理我网站上输入表单的各种复杂实例的UI交互。

使用Prototypes,我实际上最终得到了一个名为 categoryForm 的对象,其中包含以下各种方法:
- categoryForm.addEventListeners
- categoryForm.handlers
- categoryForm.validation

最后两个是包含许多不同方法的对象。 下面的代码是我完成的代码的缩减版本,但是应该足以解决问题,因为其余的是类似主题的变体。

我遇到的问题是,在下面的例子中:
- 我点击桌子上的'.addNewItems' - 这会触发我的监听器,它会调用'addNewTableItem'处理程序方法 - 处理程序然后尝试循环输入,通过'validation.checkInputVal'方法传递它们以在继续之前验证每个输入。

然而,当我们进入这个循环时, this 的范围已完全改变(如预期的那样),我不知道如何引用我的categoryForm对象并调用'验证.checkInputVal'方法。我只是得到一个错误,说这不是一个函数。(再次预料)

以下是代码:

function categoryFormFuncs(){

    // VARIABLES
    var _this               = this;
    var table               = $('table');

    // EVENT LISTENER FUNCTIONS
    this.addEventListeners = function(){

        // Listen for the AddItemButton on Tables and call the addNewTableItem function
        table.on('click', '.addNewItems', function(e){
            // Find new ItemGroup and Collect Inputs into an Array
            var newItemGroup = $(this).parents('.newItemGroup')[0];
            // Send New Item Group and Table to be updated to the Handler
            _this.handlers.addNewTableItem(newItemGroup);
        });


    }
};

// HANDLER FUNCTIONS
categoryFormFuncs.prototype.handlers = {

        // Function to Create a NewItemGroup table row
        addNewTableItem: function (inputGroup){
            var validationcheck;
            // Get all the Inputs
            var inputs = $(inputGroup).find('input');
            // Check Inputs are valid and Highlight them if not
            for(var i = 0; i < inputs.length; i++){
                validationcheck = validation.checkInputVal(inputs[i]);
                if(!validationcheck.passed){
                    $(inputs[i]).addClass('input-inValid')
                    return
                } else {
                    $(inputs[i]).removeClass('input-inValid')
                }
            };
            // If Valid, turn each input into a Table Cell and clear the original Input value
            var rowCells = ""
            for(var i = 0; i < inputs.length; i++){
                rowCells += "<td>" + $(inputs[i]).val() + "</td>";
                $(inputs[i]).val("");
            }
            // Construct the new Table row and update the DOM
            var newRow = "<tr class='itemGroup'>" + rowCells + "<td><span class='float-right remove-item fa fa-minus-circle'></span></td></tr>";
            $(inputGroup).before(newRow);
        }
}


// VALIDATION CHECKS
categoryFormFuncs.prototype.validation = {

        checkInputVal: function(input){
            if($(input).val()){
                return { passed: true }
            } else {
                return { passed: false, message: "Input with no Value"}
            }   
        }
}

var categoryForm = new categoryFormFuncs();
categoryForm.addEventListeners();

我找到了一种方法来完成这项工作,即将验证方法作为Handler的参数提供:

function categoryFormFuncs(){

    // VARIABLES
    var _this               = this;
    var table               = $('table');

    // EVENT LISTENER FUNCTIONS
    this.addEventListeners = function(){

        // Listen for the AddItemButton on Tables and call the addNewTableItem function
        table.on('click', '.addNewItems', function(e){
            // Find new ItemGroup and Collect Inputs into an Array
            var newItemGroup = $(this).parents('.newItemGroup')[0];
            // Send New Item Group and Table to be updated to the Handler
            _this.handlers.addNewTableItem(newItemGroup, _this.validation.checkInputVal);
        });


    }
};

// handlers
categoryFormFuncs.prototype.handlers = {

        // Function to Create a NewItemGroup table row
        addNewTableItem: function (inputGroup, checkInputVal){
            var validationcheck;
            // Get all the Inputs
            var inputs = $(inputGroup).find('input');
            // Check Inputs are valid and Highlight them if not
            for(var i = 0; i < inputs.length; i++){
                validationcheck = checkInputVal(inputs[i]);
                if(!validationcheck.passed){
                    $(inputs[i]).addClass('input-inValid')
                    return
                } else {
                    $(inputs[i]).removeClass('input-inValid')
                }
            };
            // If Valid, turn each input into a Table Cell and clear the original Input value
            var rowCells = ""
            for(var i = 0; i < inputs.length; i++){
                rowCells += "<td>" + $(inputs[i]).val() + "</td>";
                $(inputs[i]).val("");
            }
            // Construct the new Table row and update the DOM
            var newRow = "<tr class='itemGroup'>" + rowCells + "<td><span class='float-right remove-item fa fa-minus-circle'></span></td></tr>";
            $(inputGroup).before(newRow);
        }
}


// VALIDATION CHECKS
categoryFormFuncs.prototype.validation = {

        checkInputVal: function(input){
            if($(input).val()){
                return { passed: true }
            } else {
                return { passed: false, message: "Input with no Value"}
            }   
        }
}

var categoryForm = new categoryFormFuncs();
categoryForm.addEventListeners();

或者我也可以将_this的引用从侦听器传递给处理程序,以便访问_this.validation。 无论哪种方式,这些都感觉非常混乱和笨重的解决方案。

我的问题是: a)有没有办法,使用我的原始设计来访问验证方法? b)我应该知道这种类型的Lister / Handler / Validation场景是否有更好的建立模式?

(免责声明:我是编程新手(6个月),如果我的描述不正确,请致歉。

0 个答案:

没有答案