父视图和子视图是否可以在 Init 完成之前通过 Injection/Find 相互引用?

Is It Possible For Parent And Child Views To Reference Each Other By Injection/Find Before Init Finishes?

我希望嵌入式视图能够从父视图调用函数,因此我试图让子视图通过注入来引用其父视图。只要在 Dock 上创建嵌入式视图,这似乎就可以正常工作:

class TestView : View() {
    override val root = vbox {
        label("Parent Label")
    }

    init {
        println("Parent is instantiating.")
    }

    override fun onDock() {
        val child = find(TestView2::class)
        root.add(child)
    }

    fun doThing() {
        println("Parent is doing a thing.")
    }
}

class TestView2 : View() {
    val parentClass: TestView by inject()

    override val root = hbox {
        label("Sub-view label 1")
        label("Sub-view label 2")
    }

    init {
        println("Sub-view is instantiating.")
        parentClass.doThing()
    }
}

不过我希望它更干净一些。如果我能够在创建父根目录时使用查找功能,我会更喜欢它。这是一个问题,因为在 init 进程的任何部分调用子视图都会创建循环实例化循环。有什么方法可以避免这种情况,还是我只能接受 onDock 并处理它?

编辑:

请注意,我在一个真实的、更复杂的应用程序中再次尝试了 onDock 方法,但出现了循环检测错误。所以即使那个方法也不能保证有效。

您可以创建循环依赖,但不能在两个组件的 init 块中调用函数,因为那样无法解决。这里的主要收获是你可能正在做一些你不应该做的事情。视图不应直接相互通信。这会产生紧密耦合并防止重用。相反,您应该与以下之一进行交流:

  1. 来自 ViewModel 的状态
  2. 控制器函数调用
  3. 使用 EventBus 的事件

由于您的代码示例是编造的,因此不知道您在实际应用中究竟想实现什么,但您会在上面的列表中找到正确的方法。

我看到了在视图中调用函数并将数据直接设置到 ui 组件中的冲动,而不是大量使用绑定,而且绝对在每种情况下都有更好的方法来解决问题:)