2017-01-06 2 views
0

私は次のコードを持っている:私は、値を変更して(コミットユーザーせずにウィンドウを閉じると質問、ViewModelになど

1):

class ExampleView :View("My Example view") { 
    val model:ExampleModel by inject() 

    override val root= vbox { 
    textfield(model.data) 
    button("Commit") { 
     setOnAction { 
     model.commit() 
     closeModal() 
     } 
    } 
    button("Rollback") { 
     setOnAction { 
     model.rollback() 
     closeModal() 
     } 
    } 
    button("Just quit") { 
     setOnAction { 
     closeModal() 
     } 
    } 
    } 

} 

class Example() { 
    var data by property<String>() 
    fun dataProperty() = getProperty(Example::data) 
} 

class ExampleModel(example: Example) : ItemViewModel<Example>() { 
    init { 
    item = example 
    } 
    val data = bind { item?.dataProperty() } 
} 

class MainView : View() { 
    val example:Example 
    override val root = BorderPane() 

    init { 
    example = Example() 
    example.data = "Data for example" 
    val exampleModel = ExampleModel(example) 
    with(root){ 
     top { 
     menubar { 
      menu("Test") { 
      menuitem("Example - 1") { 
       val scope = Scope() 
       setInScope(exampleModel, scope) 
       find<ExampleView>(scope).openWindow() 
      } 
      menuitem("Example - 2") { 
       val scope = Scope() 
       setInScope(exampleModel, scope) 
       find<ExampleView>(scope).openWindow() 
      } 
      } 
     } 
     } 
    } 
    } 
} 

を、私はこの例には2つの質問がありますヘルプ[X]ボタンでこれを行うことができます)、ViewModelだけが変更を保存します(再オープン後もGUIに表示されます)が、モデルのPOJOオブジェクトは古いデータを保持します。

例クラス(DIなし)のインスタンスを使用した場合、このインスタンスはすべての変更を一度に受け取りました。

たとえば、私はコミット/ロールバック機能は望んでいませんが、DIと即時更新が必要です。私は何をすべきですか? ViewModelには、パラメータを持つコンストラクタを持っており、私はこの

find<ExampleView>(Scope()).openWindow() 

のようなオープンExampleViewを試みるならば、私は明らかにRuntimeExceptionを得ました。)

2(ofcource iは、「テキストフィールドの変化値イベント」を「コミット」を呼び出すことができます)例えば、コンパイラの警告(または何か他のもの)によってこれを避けることはできますか?

答えて

1

1)これは、ViewModelの正しいデフォルトの動作です。ビューモデルのプロパティを入力にバインドすると、その変更はすぐにそのバインディングされたプロパティに反映されますが、変更をコミットした後でのみ、基になるモデルオブジェクトにフラッシュされます。

あなたが戻って基本となるモデルオブジェクトへのビューモデルのプロパティの変更を自動コミットしたい場合は、trueに設定autocommitプロパティにバインディングを作成することができます。

val data = bind(true) { item?.dataProperty() } 

それが見える場合にもbind(autocommit = true)を書くことができますあなたにはっきりと分かります。これにより、変更が自動的に元のオブジェクトにフラッシュされます。

また、setInScopeのようにプライムしない限り、ビューモデルのコンストラクタにアイテムを必要とすることで、注入に使用されないようにすることもできます。これはあなたのユースケースでは問題ないかもしれませんが、注意する価値があります。

2)次回のTornadoFX 1.5.10では、パラメータを渡すのを忘れた場合、ランタイムエラーメッセージが表示されます。また、パラメータのデフォルト値も導入されています。詳細はhttps://github.com/edvin/tornadofx/pull/227を参照してください。