表达式

Regular里所有的绑定都与表达式有关,表达式编译结果是一个表达式对象, 熟悉本章内容可以帮助你更好的理解Regular内部的数据监听原理。

1. ES5 表达式

Regular 支持几乎所有 ES5 表达式语法,下列都是合法的表达式

  • 100 + 'b'.
  • user? 'login': 'logout'
  • title = title + '1'
  • !isLogin && this.login()
  • items[index][this.nav(item.index)].method1()

几个注意点

  1. 表达式中的this指向组件本身
  2. 数据根路径从 component.data 开始, 即user 其实获取的是component.data.user
  3. 不支持自增、自减(++,--)以及位操作符& |
  4. 不支持正则表达式的字面量
  5. 开放了部分JS内建对象:
    • Array Date JSON Math NaN RegExp Object String
    • decodeURI decodeURIComponent encodeURI encodeURIComponent
    • parseFloat parseInt

除了 ES5 的表达式,Regular 还提供了以下几种表达式类型

2. 规范外表达式类型

2.1. 一次性绑定

脏检查性能依赖于监听器的数量,Regular引入了@()预发提供了一次绑定功能: 监听器在一次变更后就会被移除。

syntax

@(Expression)

可以在任意的表达式环境使用@()(list, if... etc)

Example

<div>{ @(title) }</div> // the interpolation only trigger once

{#if @(test)}  // only test once
//...
{/if}

{#list @(items) as item}  // only trigger once
//...
{/list}
  • 你也可以在$watch 使用 @()

var component = new Regular({
  data: {
    user: {}
  }
});

var i = 0;
component.$watch("@(user.name)", function(){
    i++  // only trigger once
});
component.$update("user.name", 1);
component.$update("user.name", 2);

// update twice  but trigger once
alert(i === 1);

如上例所示,由于『脏了一次就被被抛弃』, 如果值后续继续变化,会导致UI与数据不同步。

参考

2.2. 过滤器Filter

syntax

Expression| fitlerName: arg1, arg2,... argN

Example

假设已注册 format 过滤器

<div>{list|format: 'yy-MM-dd'}</div>

参考指南

2.3. Range

Range 即数组的简写模式

Syntax:

start..end

Example

1..3 === [1,2,3]

3. 错误抑制

在动态模板中,如果抛出所有JS中常见的 xx of undefined 的错误,整个系统会变得相当脆弱。Regular 抑制了这类错误中安全的部分,并使用undefined代替


new Regular({
  template: "<div>{blog.user.name}</div>"
})

// => <div></div>

如果是方法不存在产生的错误,Regular 仍然会抛出,这属于「非安全」的错误


new Regular({
  template: "<div>{this.methodNoFound(blog.user.name)}</div>"
})

其中blog.user.name错误被抑制,而this.methodNoFound的未定义错误会被抛出

4. 表达式对象

理解表达式对象,可以帮助你使用表达式

表达式在编译后会通过new Function编译为一个 表达式对象 ,对象包含以下两个关键方法

  • get(context)

    即表达式的求值函数,函数需要传入context(Component实例)参数

    Regular的脏检查即通过比较get两次返回是否不同来判断数据是否变动。

    example:

    // create expression
    var component = new Regular({
      data: {
        user: 'leeluolee',
        age: 20 
      }
    });
    
    var expr = component.$expression("user + ':' + (age - 10)")
    
    alert(expr.get(component) === "leeluolee:10" ) //true
    
  • set(context, value) *此函数不一定存在

    如果表达式是一个合法的LeftHandSideExpression,Regular会提取set函数,用来赋值,set函数通常用于实现双向绑定。

    
    // component as context
    var component = new Regular({
      data: {
        users: [
          {name: 'leeluolee'},
          {name: 'luobo'}
        ],
        index:0
      }
    });
    
    var expr = component.$expression('users[index].name')
    
    expr.set(component, 'daluobo');
    
    alert(component.data.users[0].name === 'daluobo') // true
    

可以提取出set函数的表达式,我们称此表达式是 setable 的,如果一个不是setable的表达式应用与双向绑定(如 r-model)结合使用,将不能得到应有效果。

并不是所有表达式都可以提取出set,即代表了不是所有表达式都能完成双向绑定,比如表达式「a+b」,显然虽然我们可以获取它的值,但是我们无从知晓如何去设置a和b的值。

5. 表达式的可用场景

文档中,标记为Expression类型的场景都可以使用表达式。

results matching ""

    No results matching ""