文字列が自動的にJavaScript式に変換されて評価されることはありません。
関数a => "a.Scope == 'Framework'"
は、空でない/空白以外の文字列(真理値)を返すので、常にすべての項目に一致します。
動的評価(eval
)を使用するのではなく、そのようなアプローチが意味する重大なセキュリティ、可読性、およびツール性の欠点を踏まえ、かなり単純な述語ビルダーの作成をお勧めします。
さらに信頼性が高く、拡張性があり、保守が簡単であることに加えて、JavaScriptが有効にするエレガントなコーディングパターンや、TypeScriptによって雄弁に指定できるようにする楽しい機会が提供されます。
はここか、あなたがそれを呼び出すために選択したものは何でも、読者への課題として残されているgridFilterExpressions
配列を、取り込み例
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
.push({
memberKey: 'Scope',
compareWith: 'framework',
comparison: 'equal',
conjunction: 'and'
},
{
kind: 'memberInvocation',
memberKey: 'endsWith',
args: ['test'],
conjunction: 'or'
});
私はあなたが期待していることを理解していません。あなたのコードを暗黙に評価しないでしょう(神に感謝します) –
動的ルールを持ち、上記の例(動的フィルタ)のようにフィルタで渡す条件文を作成します –
これはうまくいかないでしょう、文字列は自動的に変換されませんJavaScript式に変換して評価します。そのフィルタは常にすべての行に一致します。 –