// 测量与绘制依赖分离:改颜色应复用尺寸缓存,改模型宽度才需要重新测量。 // ViewportBand 还显式读取实际页面视口,使原生 resize 可通过依赖触发重测。 // 只负责测量需要的宽度,和绘制颜色分成两个业务对象以便观察独立失效。 class WidthModel { width: Number // 点击把模型宽度置为 260;源 measure 读取过该字段,缓存因此失效。 function expand(self: WidthModel, event: Event): Unit { self.width = 260 } } // 保存 paint 使用的颜色,不参与 CachedRect 的测量。 class Tint { color: String // 只改颜色;正常情况下需重绘而不重新执行无关源测量。 function blue(self: Tint, event: Event): Unit { self.color = "#526AC7" } } // 原生矩形的尺寸/颜色策略分别由源协议覆盖,业务模型通过字段持有。 class CachedRect: RectBlock { dimensions: WidthModel tint: Tint // 读取 dimensions.width 返回固定高 60;实际读观察由运行时缓存记录,不手工声明依赖表。 function measure(self: CachedRect, mount: Mount, constraints: Constraints): MeasureResult { return MeasureResult(self.dimensions.width, 60) } // 复用原生矩形命令,再改新命令的颜色;修改新结果被允许,但 paint 不能修改已有业务对象。 function paint(self: CachedRect, mount: Mount, geometry: Bounds): DisplayList { drawing = RectBlock.paint(self, mount, geometry) drawing.commands.at(0).color = self.tint.color return drawing } } // 宽度来自 ui.viewport 的当前逻辑页面区域,显示窗口变化也能成为测量依赖。 class ViewportBand: RectBlock { // 返回可用视口宽度,最终仍服从父容器约束;外层 padding 会减少分配宽度。 function measure(self: ViewportBand, mount: Mount, constraints: Constraints): MeasureResult { return MeasureResult(ui.viewport().width, 24) } } // 创建相互独立的宽度/颜色模型并绑定两个按钮,用相同对象观察缓存与可见结果。 dimensions = WidthModel(200) tint = Tint("#ED6A5A") rect = CachedRect(80, 20, 0, "#ED6A5A", dimensions, tint) band = ViewportBand(80, 24, 0, "#237A45") blue = Button("只改绘制颜色") expand = Button("修改测量依赖") blueConnection = blue.on("click", tint.blue) expandConnection = expand.on("click", dimensions.expand) root = Column(24, 16, TextBlock("改变颜色保留测量缓存;改变宽度重新测量"), band, rect, blue, expand) page = Page() page.render(root)