JS Revearing Pattern事件未定义问题
JS Revealing Pattern event undefined issue
我使用JS的模块化设计模式,在使用参数绑定函数时经常遇到问题。我有一个特定的函数,我想将它绑定到不同的事件,以避免为每个绑定的事件编写函数。函数或参数中唯一的区别是将更新的表。问题是,当我用我需要的参数构建一个函数并将这些参数传递给绑定事件时,在加载时,我会在控制台中得到一个未定义的错误。请记住,我想坚持这种设计模式,因为它提供了安全性。
这是我的JS:
var Users = (function(){
var $addRoleForm = $('#addUserRole');
var $rolesTableBody = $('#table-roles tbody');
$addRoleForm.submit(ajaxUpdate(event, $rolesTableBody));
function ajaxUpdate(event, tableName) {
event.preventDefault();
event.stopPropagation();
var url = this.action;
var data = $(this).serialize();
var $this = $(this);
$.ajax({
type: 'POST',
url: url,
dataType: 'json',
data: data,
success: function(data) {
if(data.st === 0){
$messageContainer.html('<p class="alert alert-danger">' + data.msg + '</p>');
setTimeout(function(){
$messageContainer.hide();
}, 7000);
} else {
$messageContainer.html('<p class="alert alert-success">' + data.msg + '</p>');
tableName.fadeOut().html('').html(data.build).fadeIn();
$this.find('input').val('');
setTimeout(function(){
$messageContainer.hide();
}, 7000);
}
},
error: function(xhr, status, error){
console.log(xhr.responseText);
}
});
}
})();
这是我在控制台中得到的错误,加载时:
Uncaught TypeError: Cannot read property 'preventDefault' of undefined
我尝试过像这样绑定事件:$addRoleForm.on('submit', ajaxUpdate(event, $rolesTableBody));
,并收到相同的结果。
有什么办法解决这个问题吗?
您看到了这个问题,因为按照现在的编写方式,ajaxUpdate
执行,返回undefined
,然后将undefined
传递给事件侦听器,所以基本上就是这样做的:$addRoleForm.submit(undefined)
。
这里有2个选择:
1) 您可以将其封装在一个匿名函数中:
$addRoleForm.submit(function(event) {
//pass the value of "this" along using call
ajaxUpdate.call(this, event, someValue);
});
$someOtherForm.submit(function(event) {
//pass the value of "this" along using call
ajaxUpdate.call(this, event, someOtherValue);
});
2) 您可以使用bind:提前设置第一个参数
$addRoleForm.submit(ajaxUpdate.bind($addRoleForm, someValue));
$someOtherForm.submit(ajaxUpdate.bind($someOtherForm, someOtherValue));
使用这种方式,您将this
的值绑定为$addRoleForm
,并将第一个参数设置为始终为someValue
,因此它与:相同
ajaxUpdate(someValue, event) {
//value of "this" will be $addRoleForm;
}
要传递事件和自定义参数,您应该使用一个匿名函数调用
$addRoleForm.submit(function(event) {
ajaxUpdate(event, $rolesTableBody));
});
这是迄今为止最简单、可读性最好的方法。
你现在所做的等同于这个
var $addRoleForm = $('#addUserRole');
var $rolesTableBody = $('#table-roles tbody');
var resultFromCallingFunction = ajaxUpdate(event, $rolesTableBody); // undefined
$addRoleForm.submit(resultFromCallingFunction);
在您调用ajaxUpdate
函数的情况下,正如括号所做的那样,并将返回的结果传递回提交回调,在您的情况下是undefined
,这是在未指定其他值时函数返回的默认值。
你可以参考这个函数,比如这个
$addRoleForm.submit(ajaxUpdate);
但是不能传递第二个参数
问题指的是Revearing Module模式。使用这种设计的好处是可读性。使用anon函数可能会起作用,但会破坏模块模式本身的整体目的。
构造模块以帮助维护作用域的一个好方法是先设置helper函数,然后在最后调用return。
事件用例示例:
var User = function() {
// local VARS available to User
var addRoleForm = document.querySelector('#addUserRole');
var rolesTableBody = document.querySelector('#table-roles tbody');
// Helper function 1
function ajaxUpdate(tableName) {
...
}
// Helper function 2
function someFunc() {
...
}
function bindEvents() {
addRoleForm.addEventListener('submit', ajaxUpdate, false);
addRoleForm.addEventListener('click', someFunc, false);
}
function init() {
bindEvents();
}
return {
runMe:init
}
}().runMe();
有助于"模块化"您的工作流程。作为一名IIFE,你也在书写你的启示模式。这可能会在将来引起调试方面的麻烦。编辑IIFE以通过返回调用更容易维护,其他开发人员也更容易在最初使用和学习。此外,它还允许您在IFFE之外扩展到另一个模块,例如:
var Clothes = function() {
function anotherFunc() {
...
}
init() {
User.runMe();
anotherFunc();
}
return {
addClothes: init
}
}().addClothes();
我希望这有助于让你更好地理解如何/何时/为什么使用JS揭示模式。快速提示:您可以将模块制作成IIFE,这不是问题。您只是限制了您可以使用的范围的上下文。另一种方法是将var User和var Clothings封装到一个主模块中,然后使其成为IIFE。这有助于防止污染您的全局命名空间。
我上面写的例子:
// MAIN APPLICATION
var GettinDressed = (function() {
// MODULE ONE
///////////////////////////
Var User = function() {
// local VARS available to User
var addRoleForm = document.querySelector('#addUserRole');
var rolesTableBody = document.querySelector('#table-roles tbody');
// Helper function 1
function ajaxUpdate(tableName) {
...
}
// Helper function 2
function someFunc() {
...
}
function bindEvents() {
addRoleForm.addEventListener('submit', ajaxUpdate, false);
addRoleForm.addEventListener('click', someFunc, false);
}
function init() {
bindEvents();
}
return {
runMe:init,
style: someFunc
}
}();
// MODULE TWO
//////////////////////////
var Clothes = function() {
function anotherFunc() {
...
}
init() {
User.style();
anotherFunc();
}
return {
dressUp: init
}
}();
// Define order of instantiation
User.runMe();
Clothes.dressUp();
}());
- 如何消除代码中的未定义和其他问题
- 组件生命周期问题/无法处理未定义的问题
- JavaScript/jQuery JSON数组问题-值为未定义
- 使用Breeze脱机数据时出现未定义的问题不是函数
- 如何使用警报进行调试来解决(未定义的)时间问题
- SJCL的问题“;无法读取属性'替换'“未定义”;
- JSON JavaScript 未定义的变量问题
- 创建可在任何地方使用的 JS 函数?范围和功能“未定义”的问题
- 将 AJAX 传递给 PHP 时遇到问题,而是未定义
- 尝试添加到根父节点时出现 KendoUI 未定义节点问题
- 榆树早午餐编译问题:“拆分”未定义
- JavaScript,jquery中未定义的VAR的问题.如何
- JS Revearing Pattern事件未定义问题
- 未捕获引用错误:未定义问题
- Javascript未定义问题
- IE8中控制台未定义问题
- JavaScript全局变量未定义问题
- 对象未定义问题
- 使用Google' Javascript API的未定义问题
- JS对象未定义问题