2016-05-16 98 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); 
    }); 

};