Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 关于DI、ViewModel等的问题_Kotlin_Tornadofx - Fatal编程技术网

Kotlin 关于DI、ViewModel等的问题

Kotlin 关于DI、ViewModel等的问题,kotlin,tornadofx,Kotlin,Tornadofx,我有以下代码: class ExampleView :View("My Example view") { val model:ExampleModel by inject() override val root= vbox { textfield(model.data) button("Commit") { setOnAction { model.commit() closeModal() } }

我有以下代码:

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()
            }
          }
        }
      }
    }
  }
}
class ExampleView:View(“我的示例视图”){
val模型:ExampleModel by inject()
覆盖val root=vbox{
文本字段(model.data)
按钮(“提交”){
坐骨作用{
model.commit()
closeModal()
}
}
按钮(“回滚”){
坐骨作用{
model.rollback()
closeModal()
}
}
按钮(“刚刚退出”){
坐骨作用{
closeModal()
}
}
}
}
类示例(){
按属性分类的var数据()
fun dataProperty()=getProperty(示例::data)
}
类ExampleModel(示例:example):ItemViewModel(){
初始化{
项目=示例
}
val data=bind{item?.dataProperty()}
}
类MainView:View(){
示例:示例
覆盖val root=BorderPane()
初始化{
示例=示例()
example.data=“例如数据”
val exampleModel=exampleModel(示例)
带(根){
顶{
梅努巴{
菜单(“测试”){
menuitem(“示例-1”){
val scope=scope()
设置范围(示例模型、范围)
查找(范围).openWindow()
}
menuitem(“示例2”){
val scope=scope()
设置范围(示例模型、范围)
查找(范围).openWindow()
}
}
}
}
}
}
}
对于这个例子,我有两个问题:

1) 如果我更改值并关闭窗口而不提交(用户可以通过“帮助[X]按钮”执行此操作),则只有ViewModel将存储更改(即使在重新打开后,它也将显示在GUI中),但model POJO对象将保留旧数据

如果我使用了Example类的实例(没有DI),那么这个实例一次收到所有更改

例如,我不想要提交/回滚功能,但我想要DI和即时更新。我该怎么办?(当然,我可以为“textfield更改值事件”调用“提交”)

2) ViewModel具有带参数的构造函数,如果我尝试像这样打开ExampleView

find<ExampleView>(Scope()).openWindow()
find(Scope()).openWindow()
然后我得到了一个明显的运行时异常。我可以通过编译器警告(或其他方式)来避免这种情况吗

1)这是ViewModel的正确默认行为。如果将视图模型的属性绑定到输入,则更改会立即反映在该绑定属性中,但只有在提交后才会刷新到基础模型对象中

如果要将视图模型属性中的更改自动提交回基础模型对象,可以将
autocommit
属性设置为true来创建绑定:

val data = bind(true) { item?.dataProperty() }
您还可以编写
bind(autocommit=true)
,如果您看得更清楚的话。这将导致任何更改自动刷新回基础对象

我还想让您意识到,通过在视图模型的构造函数中要求一个项,您可以有效地防止它与注入一起使用,除非您像使用
setInScope
一样对其进行初始化。这对于您的用例来说可能很好,但值得注意

2) 如果忘记传递参数,即将发布的TornadFX 1.5.10将为您提供更好的运行时错误消息。它还引入了参数的默认值。有关更多信息,请参阅。

1)这是ViewModel的正确默认行为。如果将视图模型的属性绑定到输入,则更改会立即反映在该绑定属性中,但只有在提交后才会刷新到基础模型对象中

如果要将视图模型属性中的更改自动提交回基础模型对象,可以将
autocommit
属性设置为true来创建绑定:

val data = bind(true) { item?.dataProperty() }
您还可以编写
bind(autocommit=true)
,如果您看得更清楚的话。这将导致任何更改自动刷新回基础对象

我还想让您意识到,通过在视图模型的构造函数中要求一个项,您可以有效地防止它与注入一起使用,除非您像使用
setInScope
一样对其进行初始化。这对于您的用例来说可能很好,但值得注意

2) 如果忘记传递参数,即将发布的TornadFX 1.5.10将为您提供更好的运行时错误消息。它还引入了参数的默认值。有关更多信息,请参阅