在 java/kotlin 中通过 inject() 将变量传递给 class 构造函数

Passing variable to class constructor by inject() in java/kotlin

我的主要 class 设置如下:

class MyView : View() {    

    val controller: PollController by inject()
    etc
}

我想传入一个变量(比如路径文件的字符串)

class PollController : Controller() {

val currentData = SimpleStringProperty()
val stopped = SimpleBooleanProperty(true)

val scheduledService = object : ScheduledService<DataResult>() {
    init {
        period = Duration.seconds(1.0)
    }
    override fun createTask() : Task<DataResult> = FetchDataTask()
}

fun start() {
    scheduledService.restart()
    stopped.value = false
}

inner class FetchDataTask : Task<DataResult>() {

    override fun call() : DataResult {
        return DataResult(SimpleStringProperty(File(**path**).readText()))
    }

    override fun succeeded() {
        this@PollController.currentData.value = value.data.value // Here is the value of the test file
    }

}

}

[DataResult 只是一个 SimpleStringProperty 数据class]

以便 class PollController 中的函数可以引用路径文件。我不知道注射是如何工作的; @Inject 始终保持红色,添加构造函数会抛出 Controller() 对象 return

这是作用域的一个很好的用例。 Scope 将 Controller 和 ViewModel 隔离开来,这样您就可以拥有不同版本的资源的不同范围。如果你还添加一个 ViewModel 来保存你的上下文,你可以这样做:

class MyView : View() {
    val pc1: PollController by inject(Scope(PollContext("somePath")))
    val pc2: PollController by inject(Scope(PollContext("someOtherPath")))
}

现在将上下文对象添加到您的控制器,以便您可以从控制器实例中的任何函数访问它。

class PollController : Controller() {
    val context : PollContext by inject()
}

上下文对象可以包含两个 input/output 变量。在此示例中,它将输入路径作为参数。请注意,此类 ViewModel 无法由框架实例化,因此您必须像我上面显示的那样手动将其中之一放入 Scope。

class PollContext(path: String) : ViewModel() {
    val pathProperty = SimpleStringProperty(path)
    var path by pathProperty

    val currentDataProperty = SimpleStringProperty()
    var currentData by currentDataProperty
}

你可以这样做:

主应用程序

class MyApp: App(MainView::class)

主视图

class MainView : View() {
    override val root = hbox {
        add(FileView("C:\passedTestFile.txt"))
    }
}

文件视图

class FileView(filePath: String = "C:\test.txt") : View() {

    private val controller : FileController by inject(params = mapOf("pathFile" to filePath))

    override val root = hbox {
        label(controller.pathFile)
    }
}

文件控制器

class FileController: Controller() {
    val pathFile : String by param()
}

控制器使用 by param() 通过参数接受路径,视图通过构造函数参数期望此变量并在注入控制器时使用它(inject 委托有一个可选的 params 参数)。当您使用此视图(在 MainView 中)时,唯一剩下的就是在创建实例时传递文件路径。

最后是:

不管怎样,我会创建 3 层而不是两层,即经典的模型-视图-控制器(或任何派生的)层,我会将文件路径存储在模型中。