2016-05-16 54 views
0

我正在调整我的身份验证JavaScript模块,以便使用一个JavaScript类钩子.js-auth-ui来处理我的Web应用程序的身份验证,同时使用数据类型属性来引用正确的函数。如何降低根据数据类型调用回调函数的复杂度?

在扫描js钩子的DOM之后,我通过init函数运行它,如下所示,它依次运行一个exec函数,该函数可以调用回适当的函数。

我想知道是否有一种更有效的方式来编写execAuthUi函数,而不是所有其他如果根据我的linting规则增加其“复杂性”评级。

const execAuthUi = function ($element) { 
    const data = $element.data(); 

    if (data.type === "account-login-form") { 
     authLoginEmail($element, data); 
    } else if (data.type === "account-logout") { 
     authLogout($element); 
    } else if (data.type === "account-reset") { 
     authReset($element); 
    } else if (data.type === "account-signup-form") { 
     authSignup($element); 
    } 
}; 

const initAuthUi = function () { 
    const $notLoaded = $_jsElements.not(".is-initialized"); 
    let $element = null; 
    let i = $notLoaded.length; 

    for (i; i--;) { 
     $element = $_jsElements.eq(i); 

     $element.addClass("is-initialized"); 

     execAuthUi($element); 
    } 
}; 
+0

也许考虑开关/ case语句? – Spaceman

+1

也personaly我不会考虑这个和过于复杂的功能。也许你只是有一个热情的棉绒。 – Spaceman

+1

@SpaceSpace谢谢我同意,他们有点困难。但是,复杂性实际上比这个例子更加极端,所以我想提出一些更高效的方法。我还处理一些其他功能:'authLoginFacebook'和'authLoginTwitter'。这个主题中的想法非常有帮助。谢谢! – jasonbarone

回答

4

使用对象映射类型回调:

var callbackMap = { 
    'account-login-form': authLoginEmail.bind(null, $element, data), 
    'account-logout': authLogout.bind(null, $element), 
    ... 
}; 

callbackMap[data.type] && callbackMap[data.type](); 
+0

我从来没有意识到,除了'thisArg',你还可以用'bind()'绑定常规参数。很高兴遇到。 –

+0

从未见过绑定之前,一个漂亮的功能。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind,如果其他人有同样的发现。 – Spaceman

+0

好主意,这正是我一直在寻找的。我把这个想法翻了一番并调整了一下。爱它! – jasonbarone

0

你可以它,而不是使用多个elseifs一个“开关”的语句写。

我会做这样的事情

switch(data.type) { 
    case "account-login-form": 
     authLoginEmail($element, data); 
     break; 
    case "account-logout": 
     authLogout($element); 
     break; 
    case "account-reset": 
     authReset($element); 
     break; 
    case "account-signup-form": 
     authSignup($element); 
     break; 
} 

您还可以使用的情况下,你有不符合任何这些要求的方法的“默认”的情况。

0

你可以做一个开关,并将支票移出重复使用。

const dataTypeAccountLoginForm = "account-login-form"; 
const dataTypeAccountLogout = "account-logout"; 
const dataTypeAccountReset = "account-reset"; 
const dataTypeAccountSignupForm = "account-signup-form"; 

const execAuthUi = function(ele){ 
    var data = ele.data(); 

    switch(data.type) { 
    case dataTypeAccountLoginForm: 
     authLoginEmail(ele, data); 
     break; 
    case dataTypeAccountLogout: 
     authLogout(ele); 
     break; 
    case dataTypeAccountReset: 
     authReset(ele); 
     break; 
    case dataTypeAccountSignupForm: 
     authSignup(ele); 
     break; 
    } 
} 

另一种选择是抽象逻辑abit。个人意见,我认为这样做是有点矫枉过正。

var dataTypeAccountLoginForm = "account-login-form"; 
var dataTypeAccountLogout = "account-logout"; 
var dataTypeAccountReset = "account-reset"; 
var dataTypeAccountSignupForm = "account-signup-form"; 

var uiFunctions = [{ 
    key : dataTypeAccountLoginForm, 
    func : authLoginEmail 
    }, 
    { 
    key : dataTypeAccountLogout, 
    func : authLogout 
    }, 
    { 
    key : dataTypeAccountReset, 
    func : authReset 
    }, 
    { 
    key : dataTypeAccountSignupForm, 
    func : authSignup 
}]; 

var execAuthUi = function(ele){ 
    var data = ele.data(); 

    for (var i = 0; i < uiFunctions.length; i++) { 
    if (uiFunctions[i].key === data.type){ 
     uiFunctions[i].func(ele,data); 
     return; 
    } 
    } 
}; 

或者您可以使用地图功能。

var dataTypeAccountLoginForm = "account-login-form"; 
var dataTypeAccountLogout = "account-logout"; 
var dataTypeAccountReset = "account-reset"; 
var dataTypeAccountSignupForm = "account-signup-form"; 

var uiFunctions = [ 
    { 
    key : dataTypeAccountLoginForm, 
    func : authLoginEmail 
    }, 
    { 
    key : dataTypeAccountLogout, 
    func : authLogout 
    }, 
    { 
    key : dataTypeAccountReset, 
    func : authReset 
    }, 
    { 
    key : dataTypeAccountSignupForm, 
    func : authSignup 
    } 
]; 

var execAuthUi = function(ele){ 
    var data = ele.data(); 

    uiFunctions.map(function(obj){ 
    if (obj.key === data.type) 
     obj.func(ele,data); 
    }); 

};