JAVA FX语法学习----数据绑定和触发器

bind 关键字将目标变量的值与绑定表达式的值相关联。绑定表达式能够是某个基本类型的简单值、对象、函数的结果或表达式的结果。如下几节分别提供每种绑定表达式 的示例。html

在大多数实际的编程状况下,须要经过数据绑定使应用程序的图形用户界面 (Graphical User Interface, GUI) 与其底层数据同步。(GUI 编程是使用 JavaFX 构建 GUI 应用程序的主题;下面咱们将用一些非可视的示例来讲明基本的底层结构。)java

让咱们先看一个简单的示例:下面的脚本将变量 x 绑定到变量 y, 更改 x 的值,而后输出 y 的值。因为这两个变量绑定在一块儿,所以 y 值会自动更新为新值。编程

var x = 0;

def y = bind x;

x = 1;

println(y); // y now equals 1

x = 47;

println(y); // y now equals 47
 

请注意,咱们已将变量 y 声明为 def。这可防止任何代码直接 为该变量赋值(尽管容许该变量的值因绑定 (bind) 而更改)。在绑定到对象时,此约定仍适用(请回顾使 用对象中介绍的 Address):函数

var myStreet = "1 Main Street";

var myCity = "Santa Clara";

var myState = "CA";

var myZip = "95050";



def address = bind Address {

street: myStreet;

city: myCity;

state: myState;

zip: myZip;

};



println("address.street == {address.street}");

myStreet = "100 Maple Street";

println("address.street == {address.street}");
 

若是更改 myStreet 的值,address 对象内部的 street 变量将受到影响:测试

address.street == 1 Main Street

address.street == 100 Maple Street
 

请注意,更改 myStreet 的值实际上会致使建立一个新的 Address 对象,而后将该对象从新赋给 address 变量。为了跟踪所作的更改而建立新的 Address 对象,请改成直接绑定 (bind) 到该对象的实例变量:ui

def address = bind Address {

street: bind myStreet;

city: bind myCity;

state: bind myState;

zip: bind myZip;

};
 

若是要显式绑定到实例变量,还能够省略第一个 bindAddress 前面的那个):spa

def address = Address {

street: bind myStreet;

city: bind myCity;

state: bind myState;

zip: bind myZip;

};
 

前面的课程已讲授了函数,可是您还必须了解绑定函数非绑定函数之间的区别。.net

请考虑下面的函数,该函数建立和返回一个 Point 对象:code

var scale = 1.0;



bound function makePoint(xPos : Number, yPos : Number) : Point {

Point {

x: xPos * scale

y: yPos * scale

}

}



class Point {

var x : Number;

var y : Number;

}
 

这就是所谓的绑定函数,由于它前面有 bound 关键字。htm


注意: bound 关键字不能替换 bind 关键字;这两个关键字按以下所示方式结合使用。

接下来,让咱们添加一些代码来调用此函数并测试绑定:

var scale = 1.0;



bound function makePoint(xPos : Number, yPos : Number) : Point {

Point {

x: xPos * scale

y: yPos * scale

}

}



class Point {

var x : Number;

var y : Number;

}



var myX = 3.0;

var myY = 3.0;

def pt = bind makePoint(myX, myY);

println(pt.x);



myX = 10.0;

println(pt.x);



scale = 2.0;

println(pt.x);
 

此脚本的输出以下所示:

3.0

10.0

20.0
 

让咱们分析一下此脚本(一次分析一部分)。

代码:

var myX = 3.0;

var myY = 3.0;

def pt = bind makePoint(myX, myY);

println(pt.x);
 

将脚本变量 myXmyY 初始化为 3.0。 这些值随后做为参数传递给 makePoint 函数,该函数会建立并返回一个新的 Point 对象。bind 关键字(位于 makePoint 调用前面)将新建立的 Point 对象 (pt) 绑定到 makePoint 函数的结果。

接下来,代码:

myX = 10.0;

println(pt.x);
 

myX 的值更改成 10.0 并输出 pt.x 的值。输出代表 pt.x 如今也为 10.0

最后,代码:

scale = 2.0;

println(pt.x);
 

更改 scale 的值并再次输出 pt.x 的值。pt.x 的值如今为 20.0。可是,若是咱们从该函数中删除 bound 关键字(从而使其成为非绑定函数),则输出应为:

3.0

10.0

10.0
 

这是由于,非绑定函数只是在其某个参数发生变化时才被从新调用。因为 scale 不是函数的参数,所以更改它的值将不会致使另外一个函数调用。

您还能够将 bindfor 表达式结合使用。为了对此进行研究,让咱们首先定义两个序列并输出这两个序列中各个项的值:

var seq1 = [1..10];

def seq2 = bind for (item in seq1) item*2;

printSeqs();



function printSeqs() {

println("First Sequence:");

for (i in seq1){println(i);}

println("Second Sequence:");

for (i in seq2){println(i);}

}
 

seq1 包含十个项(数字 1 至 10)。seq2 也包含十个项;这些项原本会与 seq1 具备相同的值,可是咱们已经对其中的每一个项都应用了表达式 item*2, 所以它们的值将加倍。

所以,输出为:

First Sequence:

1

2

3

4

5

6

7

8

9

10

Second Sequence:

2

4

6

8

10

12

14

16

18

20
 

咱们能够经过将 bind 关键字放在 for 关键字前面来绑定这两个序列。

def seq2 = bind for (item in seq1) item*2;
 

问题如今变成:“若是 seq1 发生了某些变化,那么是 seq2 中的全部项都受到影响仍是部分项受到影响?”咱们能够经过如下方法来对此进行测试:将一个项(值 11)插入 seq1 的末尾处,而后输出这两个序列的值,看有什么变化:

var seq1 = [1..10];

def seq2 = bind for (item in seq1) item*2;

insert 11 into seq1;

printSeqs();



function printSeqs() {

println("First Sequence:");

for (i in seq1){println(i);}

println("Second Sequence:");

for (i in seq2){println(i);}

}
 

输出:

First Sequence:

1

2

3

4

5

6

7

8

9

10

11

Second Sequence:

2

4

6

8

10

12

14

16

18

20

22
 

输出代表,将 11 插入 seq1 的末尾处不会影响 seq2 中的前 10 个项;新项会自动添加到 seq2 的末尾处,其值为 22。

替换触发器是附加到变量的任意代码块,一旦变量的值发生变化,它们就会执行。如下示例显示了基本语法: 它定义一个 password 变量并向其附加一个替换触发器;当密码发生变化时,该触发器会输出一则消息来报告此变量的新值:

var password = "foo" on replace oldValue {

println(""nALERT! Password has changed!");

println("Old Value: {oldValue}");

println("New Value: {password}");

};



password = "bar";
 

此示例的输出以下所示:

ALERT! Password has changed!

Old Value:

New Value: foo



ALERT! Password has changed!

Old Value: foo

New Value: bar
 

此示例中的触发器引起两次:当 password 初始化为 "foo" 时引起一次,当其值变成 "bar" 时又引起一次。请注意,oldValue 变量存储在调用触发器以前变量的值。您能够将 oldValue 变量命名为任何所需的名称,咱们是因为该名称具备描述性才刚好使用它。



asdtiang 2010-01-15 14:35 发表评论
相关文章
相关标签/搜索