這不會起作用,字符串不會自動轉換爲JavaScript表達式並進行評估。
函數a => "a.Scope == 'Framework'"
始終匹配所有項,因爲它返回一個非空/非空白字符串,它是一個真值。
而不是使用動態評估(eval
),從而承擔這種方法所暗示的嚴格的安全性,可讀性和可修復性損害,我建議創建一個相當簡單的謂詞構建器。
除了更可靠,可擴展且更易於維護之外,它還提供了一個令人愉快的機會,可以突出顯示JavaScript啓用的一些優雅編碼模式,以及哪些TypeScript可以讓我們進行雄辯指定。
下面是一個例子
export interface MemberInvocationExpression {
kind: 'memberInvocation';
memberKey: keyof Project; // project is row type
args?: {}[];
negated?: true;
conjunction: 'and' | 'or';
};
export interface MemberComparisonExpression {
kind: 'memberComparison';
memberKey: keyof Project;
compareWith: {};
negated?: true;
comparison: 'equal' | 'notEqual' | 'greater' | 'lesser';
conjunction: 'and' | 'or';
}
export type GridFilterExpression =
| MemberInvocationExpression
| MemberComparisonExpression;
export default class {
gridFilterExpressions: GridFilterExpression[] = [];
composeFilters(): (p: Project) => boolean {
return this.gridFilterExpressions.reduce((composed, expression) => {
// every element except the first element, must specify this.
const conjunction = expression.conjunction;
const predicate = predicateFromExpression(expression);
switch (conjunction) {
case 'and':
return p => composed(p) && predicate(p);
case 'or':
return p => composed(p) || predicate(p);
default:
throw Error('Invalid composition');
}
}, _ => true);
}
}
function predicateFromExpression(expression: GridFilterExpression) {
switch (expression.kind) {
case 'memberInvocation':
return predicateFromMemberInvocationExpression(expression);
case 'memberComparison':
return predicateFromMemberComparisonExpression(expression);
case // other filter expression kinds....
default: throw Error('invalid filter');
}
}
function predicateFromMemberInvocationExpression(expression: MemberInvocationExpression) {
const {memberKey, args, negated} = expression;
const predicate = (p: Project) => p[memberKey](...args);
return negated ? (p: Project) => !predicate(p) : predicate;
}
function predicateFromMemberComparisonExpression(expression: MemberComparisonExpression) {
const {memberKey, compareWith, comparison, negated} = expression;
const predicate = (p: Project) => {
switch (comparison) {
case 'equal': return p[memberKey] === compareWith;
case 'notEqual': return p[memberKey] !== compareWith;
case 'greater': return p[memberKey] > compareWith;
case 'lesser': return p[memberKey] < compareWith;
default: throw Error('Invalid comparison in filter');
}
};
return negated ? (p: Project) => !predicate(p) : predicate;
}
填充陣列,gridFilterExpressions
或任何你選擇稱呼它,就留給讀者做練習,但是這是比較容易的部分。 嗯,這裏是根據你看到的過濾器的一個例子:
gridFilterExpressions
.push({
memberKey: 'Scope',
compareWith: 'framework',
comparison: 'equal',
conjunction: 'and'
},
{
kind: 'memberInvocation',
memberKey: 'endsWith',
args: ['test'],
conjunction: 'or'
});
我不明白你期望做什麼。它不會隱式評估你的代碼(謝天謝地) –
準備條件語句,它具有動態規則並像上面的例子(動態過濾器)那樣通過過濾器 –
這不會起作用,字符串不會自動轉換到JavaScript表達式並進行評估。該過濾器始終匹配每一行。 –