过滤器与表达式

NornJ模板的插值变量中可以使用过滤器来对数据进行一些运算、过滤操作,语法和Vue 2.0中的过滤器较为类似。

另外,模板的插值变量中也支持一些常用的js表达式,如{{ [1, 2][0] * 3 }}。然而表达式语法实际上是过滤器的语法糖写法,这是NornJ与其他模板对比的一个很有特色的地方。故NornJ中可以支持js语法中并不支持的运算符如..**等,且还可以自由扩展出更多的新运算符。

过滤器

  • 过滤器语法为{插值变量 | 过滤器1 | 过滤器2...},如使用多个过滤器则会按顺序依次执行,如下所示:
//每个过滤器都是一个函数,使用nj.registerFilter方法全局注册
nj.registerFilter('2x', num => num * 2);

console.log(nj`<div>{{100 | +(50) | 2x}}</div>`());  //输出<div>300</div>
  • 可以一次定义多个全局过滤器:
nj.registerFilter({
  trim: obj => obj.trim(),
  replace: obj => obj.replace(/id/g, 'test1')
});

局部过滤器

  • 还可以使用局部过滤器,将过滤器函数定义为插值变量即可:
nj`<div>{{1 | test}}</div>`({
  test: value => value + '_test'
});

过滤器参数

  • 过滤器也可以添加参数,语法为{插值变量 | 过滤器1(参数1,参数2...) | 过滤器2(参数1,参数2...)...}。在过滤器方法中第一个参数是当前传入的数据;从第二个参数开始依次为这些模板中传入的参数,如下所示:
nj.registerFilter('test', (obj, p1, p2) => {
  console.log(obj);  //输出test
  console.log(p1);   //输出1,过滤器参数的语法规则与插值语法相同
  console.log(p2);   //输出2,过滤器参数也可以传入插值变量动态求值
  return obj;
});

nj`<div>{{data | test(1, arg2)}}</div>`({
  data: 'test',
  arg2: 2
});
  • 在过滤器的参数中也支持嵌套过滤器:
<#if {{i | filter1(j | filter2(k | filter3))}}>...</#if>
  • 有参数的过滤器可以省略|符号,但是过滤器名称前必须有空格(至少一个空格或换行,除了几种特殊的过滤器,目前有._#三个),例如:
<#if {{i >=(0) ||(i <=(-10))}}>...</#if>

函数型过滤器

  • 还可以直接以函数调用的方式来使用过滤器,称为函数型过滤器。语法为将过滤器名称当做函数调用即可,例如:
{{ bool(1) }}

{{ 1 | bool }}

是等价的,结果都为true

注意:函数型过滤器的前面可以不加空格。

过滤器内部的options参数

  • 注册过滤器函数的最后一个参数即为options参数,它是一个对象类型。从options中可以获取到模板内部的一些值,主要用于实现一些复杂的模板扩展功能,如下所示:
nj.registerFilter('test', function(val, options) {
  const ctx = options.context;
  console.log(ctx.getData('id'));   //输出100
  console.log(ctx.data[0]);         //输出1
  console.log(ctx.parent.data[0]);  //输出{ list: [1] }
  console.log(ctx.index);           //输出0

  return val;
});

nj`
<#each {{list}}>
  {{@index | test}}
</#each>
`({ list: [1] }, { id: 100 });

options参数列表(更多参数及细节待补充):

参数名称 类型 作用
_njOpts Object 主要用在过滤器参数数量不固定时,用来判断是否为options参数
context Object 模板内部的上下文数据
lastValue Any 上一个的上一个过滤器的结果值,在过滤器函数内使用call及apply时可能会用到

表达式

  • 过滤器只传一个参数时还支持省略扩号,这样就可以用类似js表达式的格式来编写,例如:
{{i >=(0) ||(i <=(-10))}}

就可以改写为:

{{i >= 0 || (i <= -10)}}  //注意">="、"<="等符号两侧都要有至少一个空格

这种使用过滤器的方式即为NornJ模板的表达式语法,实质上是编写过滤器的一种语法糖,规则为捕获过滤器名称后面的第一个变量(包含链式的变量),正确的用法举例如下:

{{1 + 2 * 3}}    //结果为9
{{1 + (2 * 3)}}  //结果为7
{{a + b.c}}
{{a + b.c.trim() + d.e}}
{{ { a: 1, b: 2 }.b * 100 }}  //结果为200
{{ [1, 2, 3][0] + 100 }}  //结果为101
  • NornJ表达式中的运算符暂时没有优先级的概念,它会从左至右执行各种运算,并使用括号控制优先级:
{{1 + 2 * 3}}    //结果为9
{{1 + (2 * 3)}}  //结果为7

预计在NornJ未来的版本中会加入运算符优先级。

  • 运算符两侧至少要有一个空格。请注意,以下语法都是错误的:
{{1+2 * 3}}            //语法错误,"+"的两端必须有空格
{{a -b.c}}             //语法错误,"-"的两端必须有空格
{{a+ b.c.trim()+d.e}}  //语法错误,"+"的两端必须有空格

使用上述错误的语法时,NornJ会在控制台发出相应的警告信息。

预计在NornJ未来的版本中会允许运算符两侧没有空格。

内置过滤器

  • 表达式中的部分运算符及字面量(如a.b{ a: 1 }[1, 2]等)实际上都是过滤器的语法糖写法,具体请看内置过滤器

results matching ""

    No results matching ""