0

您好,我是使用 TornadoFX 的新手,我想知道 MVP 结构的最佳设计是使用 TornadoFX 吗?

在 MVP 中,视图:

-> 将所有事件(例如按钮单击)委托给演示者中的函数

-> 不与模型交互

以下是一些粗略的原型想法:

abstract class AbstractPresenter<View : tornadofx.View> : Controller() {

var view: View by Delegates.notNull()

fun attachView(view: View) {
    this.view = view;
 }
}

我创建了一个将自己附加到 AbstractView 的演示者:

abstract class AbstractView<out Presenter : AbstractPresenter<*>> : View() {

abstract val presenter: Presenter

}

现在在一个例子中使用它:

class SampleTestView: AbstractView<SampleTestPresenter>() {

override val presenter: SampleTestPresenter by inject()
override val root: AnchorPane by fxml()

val testButton: Button by fxid()

init {
    presenter.attachView(this)
    testButton.setOnAction { presenter.doSomething() }
   }

}

示例演示者:

class SampleTestPresenter: AbstractPresenter<SampleWindowView>() {

fun doSomething() {
    println("did it")
}

}

这是使用 TornadoFX 的 MVP 模式的一个不错的实现吗?

编辑

做了一些改动:

class SampleWindowView : View() {
override val root: AnchorPane by fxml()
val presenter : SampleWindowViewPresenter by inject()

val button:Button by fxid()

init {
    button.setOnAction {  presenter.handleButtonClick() }
  }
}


class SampleWindowViewPresenter : Controller() {

val sampleView: SampleWindowView by inject()

fun handleButtonClick() {
    println("clicked")
  }
}
4

1 回答 1

2

总结上面的讨论,您可以简单地执行以下操作:

class SampleTestView : View() {
    val presenter: SampleTestPresenter by inject()

    override val root: AnchorPane by fxml()
    val testButton: Button by fxid()

    init {
        testButton.setOnAction { presenter.doSomething() }
    }
}

class SampleTestPresenter : Controller() {
    val view: SampleTestView by inject()

    fun doSomething() {
        println("Did the thing")
    }
}

如果你想确保视图有一个演示者,你可以创建一个抽象视图并让你的所有视图都从它扩展:

abstract class AbstractView<Presenter : Controller> : View() {
    abstract val presenter: Presenter
}
于 2016-08-13T07:34:01.753 回答