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 發表評論
相關文章
相關標籤/搜索