[关闭]
@Ivony 2014-05-05T17:15:38.000000Z 字数 5607 阅读 3588

Jumony Binding

Jumony

Jumony Binding 是 Jumony 的一个衍生项目,这个项目使得我们通过简单的修改就能将 HTML 文档当作模板来使用。

绑定表达式

绑定表达式用于描述绑定数据源,其由一个类名(一般是eval)以及若干参数组成。绑定表达式在不同的位置需要使用不同的形式。

HTML文本绑定

下面是一段 HTML 模板,看起来像是这样:

  1. <html>
  2. <body>
  3. <div><strong>Name</strong>: <eval path="FirstName" /> <eval path="LastName"></div>
  4. </body>
  5. </html>

在其中出现的<eval path="FirstName" />就是一个数据绑定表达式。在数据绑定时,这些标签将会自动替换为实际的数据。

path 的值是一个成员选择表达式,其形式为:

  1. property-name.property-name[index-name].property-name...

其语法和 WPF 绑定表达式的 path 属性是一样的,如果你不熟悉 WPF,这个语法其实与 WebForm 中的 DataBinder.Eval( expression )的语法也是一样的。

path="FirstName"即表示取出当前数据模型的 FirstName 属性的值

HTML 属性绑定

当我们需要对属性值进行数据绑定时,则需要使用数据绑定表达式的属性形式:

  1. <a href="{eval path=Url}"><img src="{eval path=ImageUrl}" /></a>

值得注意的是,在属性中使用数据绑定表达式,需要用数据绑定表达式填满整个属性值,前后不允许出现任何其他字符,像下面的这个例子将不会被视为合法的数据绑定表达式:

  1. <img src="http://img.my-site.com/{eval path=ImageName}.jpg" />

如果我们需要进行这样的数据绑定,则需要使用 format 属性,像这样:

  1. <img src="{eval path=ImageName, format=http://img.my.com/{{0}}.jpg}" />

在上面的例子中,我们也知道如何在绑定表达式中插入"{"和"}"字符了,只需要简单的双写这两个字符,即使用"{{"和"}}"来代替"{"和"}"。

脚本绑定

最后,特别的, Jumony Binding 还提供了在客户端 JavaScript 脚本中进行数据绑定的语法:

  1. <script>
  2. var userId = null;//{eval path=UserID}
  3. </script>

在脚本中使用绑定表达式的形式为:

  1. var variable-name = any-script-expression;//{binding-expression}

其中等号后面的any-script-expression会被忽略并替换为绑定值的JSON格式。

在脚本中使用绑定表达是有几个值得注意的限制:

  1. 不能写成多行,也就是说any-script-expression必须只有一行,同时变量名和等号之间也不允许插入任何换行。

  2. 必须以var开头,如果你需要绑定到一个全局变量或是某个对象的属性,则需要先绑定到一个局部变量,再另起一行通过赋值语句赋值给全局变量或者属性。

  3. 只能对变量进行绑定,即variable-name必须是一个合法的变量名,而不能是某个对象的属性或是别的表达式。

  4. 绑定表达式必须出现在注释的最后面,在后面不允许出现除了空白字符之外的任何字符。

  5. 在脚本中使用绑定表达式不会自动对被绑定的对象调用 ToString 方法。在脚本中绑定默认将会生成目标对象的 JSON 表达形式,这使得你可以将一个复杂的对象绑定在 JavaScript 的变量上。但是如果你在绑定表达式中使用了 format 或者其他对值进行文本化的属性,则最终绑定的结果是经过处理后的字符串。

绑定表达式语法详解

对于如下绑定表达式:

  1. {eval path=Name , format= }

这个有两个属性,一个是path,其值为字符串"Name ",另一个是format,其值为字符串" "

属性名前后的空白字符将会被忽略,但属性值前后的空白字符不会忽略,}之前的空白字符也不会被忽略。

再考虑这样的绑定表达式:

  1. {eval format=, path}
  2. <eval format="" path /><!--这个是上面表达式的等价形式-->

这个绑定表达式也有两个属性,一个是format,其值为空字符串"",另一个是path,其值为空(null)。

最后,我们需要知道,绑定表达式可以嵌套:

  1. {eval format={eval path=Format}, path=Name}

一般而言,会先计算被嵌套的绑定表达式的文本表达形式的值,然后再套到外层绑定表达式,在此例中,我们假设当前数据模型的Format属性为"this is {0}",则这个绑定表达式等价于:

  1. {eval format=this is {{0}}, path=Name}

数据上下文

datamodel 属性

可以通过在元素中使用 datamodel 属性来设置当前元素的数据模型:

  1. <div datamodel="{eval path=UserData}">
  2. ...
  3. </div>

在这个元素中以及所有未设置数据上下文的子元素中,默认的模型将会变为UserData属性所指的对象。

譬如说下面两段代码是等价的:

  1. <a href="{eval path=ImageInfo.LinkUrl}"><img src="{eval path=ImageInfo.ImageUrl}" /></a>
  1. <a datamodel="{eval path=ImageInfo}" href="{eval path=LinkUrl}"><img src="{eval path=ImageUrl}" /></a>

在第二段代码中,通过datamodel="{eval path=ImageInfo}"设置了数据模型,所以在该元素及其子元素中默认的数据模型,所以所有的绑定表达式中默认的数据模型变成了ImageInfo属性所指向的对象。

设置datamodel属性也可以使得系统将数据储存下来,不会每一次绑定的时候都去获取一次对象的值。

如果需要直接绑定当前数据模型,则可以使用不带任何参数的{eval}绑定表达式:

  1. <img src="{eval}" />
  1. <eval />

最后,如果你将一个空值(null)设置到元素的当前数据模型,那么这个元素将会被直接移除。

简单列表绑定

有时候我们需要将一个数据列表绑定到模板,这个时候我们需要另一种数据绑定表达式{eval-list},这个绑定表达式只能运用在datamodel属性上。

假设当前数据模型有一个属性ImageInfos,这是一个关于图片信息的列表,其实现了IEnumerable接口(这一点很重要,一般来说只有实现了IEnumerable接口的类型可以被当作列表数据源),那么我们只需要写成这样:

  1. <a datamodel="{eval-list path=ImageInfos}" href="{eval path=LinkUrl}"><img src="{eval path=ImageUrl}" /></a>

系统会自动根据数据源中的数据项数将<a>元素复制同样的份数,并对其中每一份进行数据绑定。

{eval-list}绑定表达式支持和{eval}相同的path属性,但是很显然的,{eval-list}不支持format和其他将绑定数据源转换为字符串的属性。

{eval-list}绑定表达式运用在其他属性或是使用其标签形式都是错误的:

  1. <a href="{eval-list path=ImagesInfo}" ></a><!--错误-->
  1. <eval-list path="ImagesInfo" /><!--错误-->

复杂列表绑定

{eval-list}还支持两个额外的属性,select属性可以指定一个选择器,使得我们可以把数据绑定到符合要求的指定的子元素上去:

  1. <table datamodel="{eval-list path=DataItems, select=tr.data-item}">
  2. <thead>
  3. <tr>
  4. <td>Name</td>
  5. <td>Age</td>
  6. </tr>
  7. </thead>
  8. <tr class="data-item">
  9. <td><binding path="Name" /></td>
  10. <td><binding path="Age" /></td>
  11. </tr>
  12. <tr class="data-item alternative">
  13. <td><binding path="Name" /></td>
  14. <td><binding path="Age" /></td>
  15. </tr>
  16. <tr class="data-item">
  17. <td><binding path="Name" /></td>
  18. <td><binding path="Age" /></td>
  19. </tr>
  20. <tr class="data-item alternative">
  21. <td><binding path="Name" /></td>
  22. <td><binding path="Age" /></td>
  23. </tr>
  24. </table>

在这种模式下,系统不会自动创建被绑定元素的副本,系统只会按照满足要求的元素的出现的顺序,将数据源中的每一项设置为元素的当前数据模型。在这里我们假设数据源是一个List类型的对象,所以可以通过下标访问每一项,那么事实上上面这个模板等价于:

  1. <table>
  2. <thead>
  3. <tr>
  4. <td>Name</td>
  5. <td>Age</td>
  6. </tr>
  7. </thead>
  8. <tr datamodel="{eval path=DataItems[0]}" class="data-item">
  9. <td><binding path="Name" /></td>
  10. <td><binding path="Age" /></td>
  11. </tr>
  12. <tr datamodel="{eval path=DataItems[1]}" class="data-item alternative">
  13. <td><binding path="Name" /></td>
  14. <td><binding path="Age" /></td>
  15. </tr>
  16. <tr datamodel="{eval path=DataItems[2]}" class="data-item">
  17. <td><binding path="Name" /></td>
  18. <td><binding path="Age" /></td>
  19. </tr>
  20. <tr datamodel="{eval path=DataItems[3]}" class="data-item alternative">
  21. <td><binding path="Name" /></td>
  22. <td><binding path="Age" /></td>
  23. </tr>
  24. </table>

数据绑定器

绑定表达式可以用来描述我们需要绑定的数据,使用绑定表达式可以将这些数据简单的作为文本绑定到指定的位置。数据绑定器则用来让我们进行复杂的绑定。

样式绑定器

系统内置的样式绑定器可以协助我们更好的进行 CSS 样式、样式类以及元素可见性进行绑定,先看如下代码:

  1. <div class="item"><binding path="Name" /></div>

假设我们有一个需求,如果当前的模型处于“被选中”的状态(即数据模型的 IsSelected 属性的值为 true 的时候),我们需要给这个<div>元素增加一个样式类:selected,借助样式绑定器来非常轻松的完成这一点。

  1. <div class="item" style-class="{binding path=IsSelected, value=selected}"><binding path="Name" /></div>

value属性表示如果绑定的目标值不为false、null或者其他任何可以被转换为false的值的时候,使用value作为最终的值。在这里,这意味着如果IsSelected不为false的时候,我们就增加一个selected的样式类。

上面这段HTML代码也可以写为:

  1. <div class="item" style-class-selected="{binding path=IsSelected}"><binding path="Name" /></div>

这与上面的代码是一样的效果。

当然不仅仅是样式类,CSS样式值也可以通过相同的语法进行绑定:

  1. <div class="item" style-diaplay="{binding path=IsHidden, value=none}"><binding path="Name" /></div>

上面的模板语法表示如果IsHidden属性不为false,则设置display样式值为none。

值得注意的是,当你使用这种表达式对某个样式设置一个空值(null)的时候,这个样式将被移除。这甚至有可能会覆盖这个元素原有的样式设置:

  1. <div style="color: red;" style-color="{binding path=ForeColor}"></div>

若是ForeColor属性为null,则style="color: red;"样式设置也会被移除。

总结,样式绑定器将检测元素中符合如下语法规则的属性:

  1. style-class
  2. style-stylename
  3. style-class-classname

并将这些属性的值,应用为当前元素的样式属性和样式类。

这里还有一个值得注意的地方是,这些属性的值并不一定需要是绑定表达式,即:

  1. <div style-color="red"></div>

在进行数据绑定后,将会变为:

  1. <div style="color: red;"></div>

表单绑定器

尚未实现

脚本绑定器

尚未实现

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注