首页 > 解决方案 > 项目属性更改时如何更新 ItemFragment

问题描述

我对 anItemViewModel与其基础项目之间的关系感到非常困惑。我正在尝试在屏幕上显示徽章,然后如果徽章在另一个线程上“实现”,则徽章应该在屏幕上更新。

现在,徽章代码如下所示:

class Badge {
  val achievedProperty = SimpleBooleanProperty(this, "achieved", false)
  var achieved by achievedProperty
}

class BadgeModel: ItemViewModel<Badge>() {
  val achieved = bind(Badge::achievedProperty)
}

接下来,我想在屏幕上显示它,在一个ItemFragment子类中:

class BadgeFragment(badge: Badge): ItemFragment<Badge>() {

  private val model: BadgeModel by inject()
  
  init {
    model.item = badge
  }

  override val root = rectangle {
    width = 50
    height = 50
    stroke = Color.BLACK
    fill = if (model.achieved) Color.RED else Color.GREEN
  }
}

这可以很好地开始,但如果我随后设置badge.achieved = true(在我的控制器中),屏幕上徽章的颜色不会改变。

我显然遗漏了一些关于对象和模型之间关系的东西,但是我在从文档中弄清楚它时遇到了很多麻烦。有人可以帮我让我的片段按照我想要的方式工作吗?

标签: kotlinjavafxtornadofx

解决方案


您的问题并非特定于模型或几乎任何与 TornadoFX 相关的东西。您编写它的方式仅在创建时检查一次颜色。您需要使用属性或绑定来监听属性更改:

class Test : Fragment() {
    val modelAchieved = SimpleBooleanProperty(true) // pretend this is model.achieved
    val achievedColor = modelAchieved.objectBinding { isAchieved ->
        if (isAchieved == true) Color.RED
        else Color.GREEN
    }

    override val root = vbox {
        togglebutton("Toggle") {
            selectedProperty().bindBidirectional(modelAchieved)
        }
        rectangle(width = 50, height = 50) {
            stroke = Color.BLACK
            fillProperty().bind(achievedColor)
        }
    }
}

我还将视图模型和片段的项目属性双向绑定在一起,以便它们保持同步。或者只使用常规片段,并自行引用模型的 item 属性。


推荐阅读