タスクのリストを維持するダミーアプリケーションを作成しようとしています。
今のところ、私がやろうとしているのはリストに追加することだけです。テキストボックスにタスク名を入力し、[タスクの追加]ボタンをクリックすると、リストが新しいアイテムで更新され、タスク名の入力がクリアされることを期待しています。タスク名が空でない場合にのみタスクを追加できるようにしたい。以下のコードは私の実装ですが、バインディングに関して質問があります。
テキストボックスのテキスト変数をビューモデルの文字列にバインドし、ボタンの無効化変数をビューモデルのブール値にバインドしています。
タスク名が変更されたときに無効状態を更新するトリガーがあります。タスク名のバインドが発生すると、ブール値はそれに応じて更新されますが、ボタンは無効のまま表示されます。しかし、ボタンの上にマウスを置くと、ボタンが有効になります。これは、JavaFX 1.3のバインディングが怠惰であるためだと思います。バインドされた変数は、読み取られたときにのみ更新されます。
また、タスクを追加すると、モデル内のタスク名をクリアしますが、テキストボックスのテキストは変更されません-を使用している場合でもbind with inverse。
テキストボックスのテキストとボタンの無効な状態を、予想どおりにバインディングを介して自動的に更新する方法はありますか?
ありがとう、
ジェームズ
AddTaskViewModel.fx:
package jamiebarrow;
import java.lang.System;
public class AddTaskViewModel {
function logChange(prop:String,oldValue,newValue):Void {
println("{System.currentTimeMillis()} : {prop} [{oldValue}] to [{newValue}] ");
}
public var newTaskName: String on replace old {
logChange("newTaskName",old,newTaskName);
isAddTaskDisabled = (newTaskName == null or newTaskName.trim().length() == 0);
};
public var isAddTaskDisabled: Boolean on replace old {
logChange("isAddTaskDisabled",old,isAddTaskDisabled);
};
public var taskItems = [] on replace old {
logChange("taskItems",old,taskItems);
};
public function addTask() {
insert newTaskName into taskItems;
newTaskName = "";
}
}
Main.fx:
package jamiebarrow;
import javafx.scene.control.Button;
import javafx.scene.control.TextBox;
import javafx.scene.control.ListView;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.scene.layout.HBox;
def viewModel = AddTaskViewModel{};
var txtName: TextBox = TextBox {
text: bind viewModel.newTaskName with inverse
onKeyTyped: onKeyTyped
};
function onKeyTyped(event): Void {
txtName.commit(); // ensures model is updated
cmdAddTask.disable = viewModel.isAddTaskDisabled;// the binding only occurs lazily, so this is needed
}
var cmdAddTask = Button {
text: "Add"
disable: bind viewModel.isAddTaskDisabled with inverse
action: onAddTask
};
function onAddTask(): Void {
viewModel.addTask();
}
var lstTasks = ListView {
items: bind viewModel.taskItems with inverse
};
Stage {
scene: Scene {
content: [
VBox {
content: [
HBox {
content: [
txtName,
cmdAddTask
]
},
lstTasks
]
}
]
}
}