我正在使用包含以下帮助程序类和方法的VueJS应用程序:
class BiometricMap {
static get(bioType) {
if (!bioType) {
return BiometricMap.default();
}
const bioTypes = {
40: () => this.getFace(),
41: () => this.getFace(),
42: () => this.getFace(),
43: () => this.getFace(),
60: () => this.getVoice(),
61: () => this.getVoice(),
140: () => this.getPin(),
141: () => this.getPin(),
150: () => this.getPalm(),
152: () => this.getPalm(),
};
return (bioTypes[bioType])();
}
static getFace() {
return {
friendly: 'Face',
type: 'face',
icon: 'face',
};
}
static getPalm() {
return {
friendly: 'Palm',
type: 'palm',
icon: 'pan_tool',
};
}
static getPin() {
return {
friendly: 'PIN',
type: 'pin',
icon: 'radio_button_checked',
};
}
static getVoice() {
return {
friendly: 'Voice',
type: 'voice',
icon: 'keyboard_voice',
};
}
static default() {
return {
friendly: '',
type: '',
icon: '',
};
}
}
export default BiometricMap;
我需要将其转换为动态的,因为bioTypes
值的列表可以更改,因此我像这样修改了get()
:
import BiometricService from '../services/BiometricService';
...
static async get(bioType) {
if (!bioType) {
return BiometricMap.default();
}
const bioTypes = {};
const baseBioTypes = await BiometricService.fetchAll();
baseBioTypes.data.forEach((type) => {
// Yet another place we have to convert 'passphrase' to 'voice'.
const captureType = type.captureType === 'passphrase' ? 'voice' : type.captureType;
const methodName = `get${captureType.charAt(0).toUpperCase() + captureType.slice(1)}()`;
bioTypes[type.bioType] = () => this[methodName];
});
return (bioTypes[bioType])();
}
这似乎起作用,因为我正确地生成了methodName
值并将其添加到bioTypes
对象中。但是,当到达
return (bioTypes[bioType])();
它没有调用适当的方法(例如getFace()
,getVoice()
等)。我在填充bioTypes
对象的方式上需要做哪些更改,以便调用适当的方法?
答案 0 :(得分:0)
此行似乎有可能是错误的:
const methodName = `get${captureType.charAt(0).toUpperCase() + captureType.slice(1)}()`;
因此,如果captureType
为voice
,则methodName
将为getVoice()
。我认为您不希望()
结尾。
然后是这个
bioTypes[type.bioType] = () => this[methodName];
如果我们将其全部写清楚,就会发现问题出在哪里:
bioTypes[type.bioType] = function () {
// Ignoring the scoping issue for a moment...
return this[methodName];
}
该函数将返回您的方法,而不是调用它。
您反而想要:
bioTypes[type.bioType] = () => this[methodName]();
下面是纠正错误的完整示例:
BiometricService = {
async fetchAll () {
return {
data: [
{ bioType: 40, captureType: 'face' },
{ bioType: 41, captureType: 'face' },
{ bioType: 42, captureType: 'face' },
{ bioType: 43, captureType: 'face' },
{ bioType: 60, captureType: 'passphrase' },
{ bioType: 61, captureType: 'passphrase' },
{ bioType: 140, captureType: 'pin' },
{ bioType: 141, captureType: 'pin' },
{ bioType: 150, captureType: 'palm' },
{ bioType: 152, captureType: 'palm' }
]
};
}
};
class BiometricMap {
static async get(bioType) {
if (!bioType) {
return BiometricMap.default();
}
const bioTypes = {};
const baseBioTypes = await BiometricService.fetchAll();
baseBioTypes.data.forEach((type) => {
// Yet another place we have to convert 'passphrase' to 'voice'.
const captureType = type.captureType === 'passphrase' ? 'voice' : type.captureType;
const methodName = `get${captureType.charAt(0).toUpperCase()}${captureType.slice(1)}`;
bioTypes[type.bioType] = () => this[methodName]();
});
return (bioTypes[bioType])();
}
static getFace() {
return {
friendly: 'Face',
type: 'face',
icon: 'face',
};
}
static getPalm() {
return {
friendly: 'Palm',
type: 'palm',
icon: 'pan_tool',
};
}
static getPin() {
return {
friendly: 'PIN',
type: 'pin',
icon: 'radio_button_checked',
};
}
static getVoice() {
return {
friendly: 'Voice',
type: 'voice',
icon: 'keyboard_voice',
};
}
static default () {
return {
friendly: '',
type: '',
icon: '',
};
}
}
(async () => {
console.log('40 :', await BiometricMap.get(40));
console.log('60 :', await BiometricMap.get(60));
console.log('140 :', await BiometricMap.get(140));
console.log('150 :', await BiometricMap.get(150));
})()
我要补充一点,每次加载所有bioTypes
,在bioTypes
中建立一个数据结构,然后调用其中一个,将所有其他都扔掉,这似乎有些奇怪。实现单个方法调用似乎正在进行很多工作。
以目前的形式,可以简化为:
static async get(bioType) {
if (!bioType) {
return BiometricMap.default();
}
const baseBioTypes = await BiometricService.fetchAll();
for (const type of baseBioTypes.data) {
if (type.bioType === bioType) {
const captureType = type.captureType === 'passphrase' ? 'voice' : type.captureType
const methodName = `get${captureType.charAt(0).toUpperCase()}${captureType.slice(1)}`
return this[methodName]()
}
}
// TODO: Handle fall-through
}
要使现有版本有意义,就需要采用某种方式保留对象bioTypes
,以便多次使用该对象。即使那样,我还是更倾向于只包含从bioType
到methodName
字符串的映射,而不是创建所有这些包装函数。